From ea95202c95ecbb4428ba153519eb23ec8c09ec99 Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Mon, 25 Mar 2019 12:53:45 +0100 Subject: [PATCH 1/7] ENH: additional constructor and methods for PDRblock (#1216) - construct from positions - reset positions, minEdgeLen, find grid index ENH: add accessor for obtaining the size of a single i-j-k dimension - eg, obtain the 'i' dimension with any of these methods: ijkAddr.size(vector::X) ijkAddr.sizes().x() ijkAddr.sizes()[0] --- src/OpenFOAM/meshes/ijkMesh/IjkField.H | 6 + src/OpenFOAM/meshes/ijkMesh/IjkFieldI.H | 10 + src/OpenFOAM/meshes/ijkMesh/ijkAddressing.H | 18 +- src/OpenFOAM/meshes/ijkMesh/ijkAddressingI.H | 13 +- src/OpenFOAM/meshes/ijkMesh/ijkMeshI.H | 4 +- src/mesh/blockMesh/Make/files | 1 + src/mesh/blockMesh/PDRblockMesh/PDRblock.C | 251 +++++++++++++++--- src/mesh/blockMesh/PDRblockMesh/PDRblock.H | 82 +++++- src/mesh/blockMesh/PDRblockMesh/PDRblockI.H | 65 ++++- .../blockMesh/PDRblockMesh/PDRblockLocation.C | 108 ++++++++ 10 files changed, 490 insertions(+), 68 deletions(-) create mode 100644 src/mesh/blockMesh/PDRblockMesh/PDRblockLocation.C diff --git a/src/OpenFOAM/meshes/ijkMesh/IjkField.H b/src/OpenFOAM/meshes/ijkMesh/IjkField.H index 0e21e473e1..b748b0ea5c 100644 --- a/src/OpenFOAM/meshes/ijkMesh/IjkField.H +++ b/src/OpenFOAM/meshes/ijkMesh/IjkField.H @@ -104,6 +104,12 @@ public: //- Return i,j,k addressing sizes for modification inline labelVector& sizes(); + //- The field size + using Field::size; + + //- The addressing dimension in the given direction + inline const label& size(const vector::components cmpt) const; + // Edit diff --git a/src/OpenFOAM/meshes/ijkMesh/IjkFieldI.H b/src/OpenFOAM/meshes/ijkMesh/IjkFieldI.H index 8943bfa5dc..09da6a5c32 100644 --- a/src/OpenFOAM/meshes/ijkMesh/IjkFieldI.H +++ b/src/OpenFOAM/meshes/ijkMesh/IjkFieldI.H @@ -157,6 +157,16 @@ inline Foam::labelVector& Foam::IjkField::sizes() } +template +inline const Foam::label& Foam::IjkField::size +( + const vector::components cmpt +) const +{ + return ijk_.size(cmpt); +} + + template inline void Foam::IjkField::clear() { diff --git a/src/OpenFOAM/meshes/ijkMesh/ijkAddressing.H b/src/OpenFOAM/meshes/ijkMesh/ijkAddressing.H index 215acbd8ad..93889dce08 100644 --- a/src/OpenFOAM/meshes/ijkMesh/ijkAddressing.H +++ b/src/OpenFOAM/meshes/ijkMesh/ijkAddressing.H @@ -36,6 +36,7 @@ SourceFiles #define ijkAddressing_H #include "labelVector.H" +#include "vector.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -72,17 +73,20 @@ public: // Access - //- Return the i,j,k addressing sizes + //- Addressing is considered empty if any component is zero + inline bool empty() const; + + //- The (i,j,k) addressing dimensions inline const labelVector& sizes() const; - //- Return the i,j,k addressing sizes for modification + //- Return the (i,j,k) dimensions for modification inline labelVector& sizes(); //- Return the total i*j*k size inline label size() const; - //- Addressing is considered empty if any component is zero - inline bool empty() const; + //- The addressing dimension in the given direction + inline const label& size(const vector::components cmpt) const; //- Reset to (0,0,0) sizing inline void clear(); @@ -93,13 +97,13 @@ public: //- Change the sizing parameters inline void reset(const labelVector& newSizes); - //- Linear addressing index (offset) for an i,j,k position. + //- Linear addressing index (offset) for an (i,j,k) position. inline label index(const label i, const label j, const label k) const; - //- Linear addressing index (offset) for an i,j,k position. + //- Linear addressing index (offset) for an (i,j,k) position. inline label index(const labelVector& ijk) const; - //- The i,j,k indexing from linear addressing. + //- The (i,j,k) indexing from linear addressing. inline labelVector index(const label idx) const; diff --git a/src/OpenFOAM/meshes/ijkMesh/ijkAddressingI.H b/src/OpenFOAM/meshes/ijkMesh/ijkAddressingI.H index adb11da793..9affedece1 100644 --- a/src/OpenFOAM/meshes/ijkMesh/ijkAddressingI.H +++ b/src/OpenFOAM/meshes/ijkMesh/ijkAddressingI.H @@ -58,6 +58,12 @@ inline Foam::ijkAddressing::ijkAddressing // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // +inline bool Foam::ijkAddressing::empty() const +{ + return (!sizes_.x() || !sizes_.y() || !sizes_.z()); +} + + inline const Foam::labelVector& Foam::ijkAddressing::sizes() const { return sizes_; @@ -77,9 +83,12 @@ inline Foam::label Foam::ijkAddressing::size() const } -inline bool Foam::ijkAddressing::empty() const +inline const Foam::label& Foam::ijkAddressing::size +( + const vector::components cmpt +) const { - return (!sizes_.x() || !sizes_.y() || !sizes_.z()); + return sizes_[cmpt]; } diff --git a/src/OpenFOAM/meshes/ijkMesh/ijkMeshI.H b/src/OpenFOAM/meshes/ijkMesh/ijkMeshI.H index da73e24be3..7a5c2af731 100644 --- a/src/OpenFOAM/meshes/ijkMesh/ijkMeshI.H +++ b/src/OpenFOAM/meshes/ijkMesh/ijkMeshI.H @@ -143,13 +143,13 @@ inline Foam::label Foam::ijkMesh::nBoundaryFaces return n.y()*n.z(); break; - // Face 2, 3 == y-min, y-max + // Face 2,3 == y-min, y-max case 2: case 3: return n.z()*n.x(); break; - // Face 4, 5 == z-min, z-max + // Face 4,5 == z-min, z-max case 4: case 5: return n.x()*n.y(); diff --git a/src/mesh/blockMesh/Make/files b/src/mesh/blockMesh/Make/files index 84473bfc0f..8193f56e1a 100644 --- a/src/mesh/blockMesh/Make/files +++ b/src/mesh/blockMesh/Make/files @@ -41,5 +41,6 @@ blockMeshTools/blockMeshTools.C PDRblockMesh/PDRblock.C PDRblockMesh/PDRblockCreate.C +PDRblockMesh/PDRblockLocation.C LIB = $(FOAM_LIBBIN)/libblockMesh diff --git a/src/mesh/blockMesh/PDRblockMesh/PDRblock.C b/src/mesh/blockMesh/PDRblockMesh/PDRblock.C index cca8eb39a2..b591fa42e9 100644 --- a/src/mesh/blockMesh/PDRblockMesh/PDRblock.C +++ b/src/mesh/blockMesh/PDRblockMesh/PDRblock.C @@ -39,8 +39,87 @@ namespace Foam } +// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // + +bool Foam::PDRblock::checkMonotonic +( + const direction cmpt, + const UList& pts +) +{ + const label len = pts.size(); + + if (!len) + { + return false; + } + + const scalar& minVal = pts[0]; + + for (label i=1; i < len; ++i) + { + if (pts[i] <= minVal) + { + FatalErrorInFunction + << "Points in " << vector::componentNames[cmpt] + << " direction do not increase monotonically" << nl + << flatOutput(pts) << nl << nl + << exit(FatalError); + } + } + + return true; +} + + // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // +void Foam::PDRblock::adjustSizes() +{ + // Adjust i-j-k addressing + sizes().x() = grid_.x().nCells(); + sizes().y() = grid_.y().nCells(); + sizes().z() = grid_.z().nCells(); + + if (sizes().x() <= 0 || sizes().y() <= 0 || sizes().z() <= 0) + { + // Sanity check. Silently disallow bad sizing + ijkMesh::clear(); + + grid_.x().clear(); + grid_.y().clear(); + grid_.z().clear(); + + bounds_ = boundBox::invertedBox; + minEdgeLen_ = Zero; + return; + } + + // Adjust boundBox + bounds_.min().x() = grid_.x().first(); + bounds_.min().y() = grid_.y().first(); + bounds_.min().z() = grid_.z().first(); + + bounds_.max().x() = grid_.x().last(); + bounds_.max().y() = grid_.y().last(); + bounds_.max().z() = grid_.z().last(); + + // Min edge length + minEdgeLen_ = GREAT; + + for (direction cmpt=0; cmpt < vector::nComponents; ++cmpt) + { + const label nEdge = grid_[cmpt].nCells(); + + for (label edgei=0; edgei < nEdge; ++edgei) + { + const scalar len = grid_[cmpt].width(edgei); + minEdgeLen_ = min(minEdgeLen_, len); + } + } +} + + void Foam::PDRblock::readGridControl ( const direction cmpt, @@ -89,22 +168,7 @@ void Foam::PDRblock::readGridControl } // Do points increase monotonically? - { - const scalar& minVal = knots.first(); - - for (label pointi = 1; pointi < knots.size(); ++pointi) - { - if (knots[pointi] <= minVal) - { - FatalIOErrorInFunction(dict) - << "Points are not monotonically increasing:" - << " in " << vector::componentNames[cmpt] - << " direction" << nl - << exit(FatalIOError); - } - } - } - + checkMonotonic(cmpt, knots); if (verbose_) { @@ -394,6 +458,33 @@ void Foam::PDRblock::readBoundary(const dictionary& dict) // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // +Foam::PDRblock::PDRblock +( + const UList& xgrid, + const UList& ygrid, + const UList& zgrid +) +: + PDRblock() +{ + // Default boundaries with patchi == shapeFacei + patches_.resize(6); + for (label patchi=0; patchi < 6; ++patchi) + { + patches_.set(patchi, new boundaryEntry()); + + boundaryEntry& bentry = patches_[patchi]; + + bentry.name_ = "patch" + Foam::name(patchi); + bentry.type_ = "patch"; + bentry.size_ = 0; + bentry.faces_ = labelList(one(), patchi); + } + + reset(xgrid, ygrid, zgrid); +} + + Foam::PDRblock::PDRblock(const dictionary& dict, bool verbose) : PDRblock() @@ -411,50 +502,124 @@ bool Foam::PDRblock::read(const dictionary& dict) // Mark no scaling with invalid value const scalar scaleFactor = dict.lookupOrDefault("scale", -1); - // Grid controls readGridControl(0, dict.subDict("x"), scaleFactor); readGridControl(1, dict.subDict("y"), scaleFactor); readGridControl(2, dict.subDict("z"), scaleFactor); - // Adjust i-j-k addressing - sizes().x() = grid_.x().nCells(); - sizes().y() = grid_.y().nCells(); - sizes().z() = grid_.z().nCells(); + adjustSizes(); - // Adjust boundBox - bounds_.min().x() = grid_.x().first(); - bounds_.min().y() = grid_.y().first(); - bounds_.min().z() = grid_.z().first(); - - bounds_.max().x() = grid_.x().last(); - bounds_.max().y() = grid_.y().last(); - bounds_.max().z() = grid_.z().last(); - - - // Boundaries readBoundary(dict); return true; } +void Foam::PDRblock::reset +( + const UList& xgrid, + const UList& ygrid, + const UList& zgrid +) +{ + static_cast(grid_.x()) = xgrid; + static_cast(grid_.y()) = ygrid; + static_cast(grid_.z()) = zgrid; + + #ifdef FULLDEBUG + for (direction cmpt=0; cmpt < vector::nComponents; ++cmpt) + { + checkMonotonic(cmpt, grid_[cmpt]); + } + #endif + + adjustSizes(); + + // Adjust boundaries + for (boundaryEntry& bentry : patches_) + { + bentry.size_ = 0; + + // Count patch faces + for (const label shapeFacei : bentry.faces_) + { + bentry.size_ += nBoundaryFaces(shapeFacei); + } + } +} + + +bool Foam::PDRblock::findCell(const point& pt, labelVector& pos) const +{ + // Out-of-bounds is handled explicitly, for efficiency and consistency, + // but principally to ensure that findLower() returns a valid + // result when the point is to the right of the bounds. + + // Since findLower returns the lower index, it corresponds to the + // cell in which the point is found + + if (!bounds_.contains(pt)) + { + return false; + } + + for (direction cmpt=0; cmpt < labelVector::nComponents; ++cmpt) + { + // Binary search + pos[cmpt] = findLower(grid_[cmpt], pt[cmpt]); + } + + return true; +} + + +bool Foam::PDRblock::gridIndex +( + const point& pt, + labelVector& pos, + const scalar relTol +) const +{ + const scalar tol = relTol * minEdgeLen_; + + for (direction cmpt=0; cmpt < labelVector::nComponents; ++cmpt) + { + // Linear search + pos[cmpt] = grid_[cmpt].findIndex(pt[cmpt], tol); + + if (pos[cmpt] < 0) return false; + } + + return true; +} + + Foam::labelVector Foam::PDRblock::findCell(const point& pt) const { - // Out-of-bounds is handled explicitly, for efficiency and consistency, - // but principally to ensure that findLower() returns a valid - // result when the point is to the right of the bounds. + labelVector pos; - labelVector pos(-1,-1,-1); - if (bounds_.contains(pt)) + if (findCell(pt, pos)) { - for (direction cmpt=0; cmpt < labelVector::nComponents; ++cmpt) - { - // Binary search - pos[cmpt] = findLower(grid_[cmpt], pt[cmpt]); - } + return pos; } - return pos; + return labelVector(-1,-1,-1); +} + + +Foam::labelVector Foam::PDRblock::gridIndex +( + const point& pt, + const scalar relTol +) const +{ + labelVector pos; + + if (gridIndex(pt, pos, relTol)) + { + return pos; + } + + return labelVector(-1,-1,-1); } diff --git a/src/mesh/blockMesh/PDRblockMesh/PDRblock.H b/src/mesh/blockMesh/PDRblockMesh/PDRblock.H index 8ee0df830a..91e16b66e2 100644 --- a/src/mesh/blockMesh/PDRblockMesh/PDRblock.H +++ b/src/mesh/blockMesh/PDRblockMesh/PDRblock.H @@ -44,10 +44,10 @@ Description Grid coordinate controls \table - Property| Description | Required | Default - points | Locations defining the mesh segment | yes | - nCells | Divisions per mesh segment | yes | - ratios | Expansion ratio (end/start) per segment | no | uniform + Property| Description | Required | Default + points | Locations defining the mesh segment | yes | + nCells | Divisions per mesh segment | yes | + ratios | Expansion ratio (end/start) per segment | no | uniform \endtable The expansion ratios are defined as per blockMesh and represent the ratio @@ -98,14 +98,20 @@ public: : public scalarList { + //- The locations are valid if they contain 2 or more points + inline bool valid() const; + //- The number of cells in this direction. inline label nCells() const; //- The number of points in this direction. inline label nPoints() const; - //- The number of divisions (nCells) in this direction. - inline label size() const; + //- True if the location is within the range + inline bool contains(const scalar p) const; + + //- Mid-point location, zero for an empty list. + inline scalar centre() const; //- Check that element index is within valid range. inline void checkIndex(const label i) const; @@ -114,7 +120,22 @@ public: inline scalar width(const label i) const; //- Cell centre at element position. + // Treats -1 and nCells positions like a halo cell. inline scalar C(const label i) const; + + //- Find the cell index enclosing this location + // \return -1 for out-of-bounds + label findCell(const scalar p) const; + + //- Find the grid index, within the given tolerance + // Return -1 for out-of-bounds and -2 for a point that is + // within bounds, but not aligned with a grid point. + label findIndex(const scalar p, const scalar tol) const; + + //- If out of range, return the respective min/max limits, + //- otherwise return the value itself. + // If the range is invalid, always return the value. + inline const scalar& clip(const scalar& val) const; }; @@ -153,9 +174,18 @@ private: //- The boundary patch information PtrList patches_; + //- The min edge length + scalar minEdgeLen_; + // Private Member Functions + //- Check that points increase monotonically + static bool checkMonotonic(const direction cmpt, const UList& pts); + + //- Adjust sizing for updated grid points + void adjustSizes(); + //- Read and define grid points in given direction void readGridControl ( @@ -167,7 +197,6 @@ private: //- Read "boundary" information void readBoundary(const dictionary& dict); - //- Populate point field for the block void createPoints(pointField& pts) const; @@ -181,7 +210,6 @@ private: labelList::iterator& neiIter ) const; - //- Add boundary faces for the shape face to lists // Lists must be properly sized! // \return the number of faces added @@ -192,6 +220,19 @@ private: labelList::iterator& ownIter ) const; + //- Obtain i,j,k index for cell enclosing this location + // \return false for out-of-bounds + bool findCell(const point& pt, labelVector& pos) const; + + //- Obtain i,j,k grid index for point location + // \return false for out-of-bounds and off-grid + bool gridIndex + ( + const point& pt, + labelVector& pos, + const scalar tol + ) const; + public: @@ -200,6 +241,14 @@ public: //- Construct zero-size inline PDRblock(); + //- Construct from components + PDRblock + ( + const UList& xgrid, + const UList& ygrid, + const UList& zgrid + ); + //- Construct from dictionary explicit PDRblock(const dictionary& dict, bool verbose=false); @@ -209,6 +258,14 @@ public: //- Read dictionary bool read(const dictionary& dict); + //- Reset grid locations and mesh i-j-k sizing + void reset + ( + const UList& xgrid, + const UList& ygrid, + const UList& zgrid + ); + // Access @@ -221,6 +278,9 @@ public: //- The mesh bounding box inline const boundBox& bounds() const; + //- The min edge length + inline const scalar& minEdgeLen() const; + //- Cell size in x-direction at i position. inline scalar dx(const label i) const; @@ -272,6 +332,12 @@ public: // The value (-1,-1,-1) is returned for out-of-bounds (not found). labelVector findCell(const point& pt) const; + //- Obtain i,j,k grid index for point location within specified + // relative tolerance of the minEdgeLen. + // The value (-1,-1,-1) is returned for out-of-bounds (not found). + // and off-grid + labelVector gridIndex(const point& pt, const scalar relTol=0.01) const; + // Mesh generation diff --git a/src/mesh/blockMesh/PDRblockMesh/PDRblockI.H b/src/mesh/blockMesh/PDRblockMesh/PDRblockI.H index 64becbd4b8..a624ee68a6 100644 --- a/src/mesh/blockMesh/PDRblockMesh/PDRblockI.H +++ b/src/mesh/blockMesh/PDRblockMesh/PDRblockI.H @@ -31,12 +31,19 @@ inline Foam::PDRblock::PDRblock() verbose_(false), grid_(), bounds_(), - patches_() + patches_(), + minEdgeLen_(Zero) {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // +inline bool Foam::PDRblock::location::valid() const +{ + return (scalarList::size() > 1); +} + + inline Foam::label Foam::PDRblock::location::nCells() const { return (scalarList::size()-1); @@ -49,19 +56,25 @@ inline Foam::label Foam::PDRblock::location::nPoints() const } -inline Foam::label Foam::PDRblock::location::size() const +inline bool Foam::PDRblock::location::contains(const scalar p) const { - return (scalarList::size()-1); + return (scalarList::size() > 1 && first() <= p && p <= last()); +} + + +inline Foam::scalar Foam::PDRblock::location::centre() const +{ + return scalarList::empty() ? 0 : (0.5*first() + 0.5*last()); } inline void Foam::PDRblock::location::checkIndex(const label i) const { - if (i < 0 || i >= size()) + if (i < 0 || i >= nCells()) { FatalErrorInFunction << "The index " << i - << " is out of range [0," << size() << ']' << nl + << " is out of range [0," << nCells() << ']' << nl << abort(FatalError); } } @@ -79,11 +92,45 @@ inline Foam::scalar Foam::PDRblock::location::width(const label i) const inline Foam::scalar Foam::PDRblock::location::C(const label i) const { + if (i == -1) + { + #ifdef FULLDEBUG + checkIndex(0); + #endif + + // "Halo" centre [-1] == x0 - 1/2 (x1 - x0) + return first() - 0.5*(operator[](1) - first()); + } + else if (i > 1 && i == scalarList::size()-1) + { + // "Halo" centre [nCells] == xN + 1/2 (xN - xN1) + return last() + 0.5*(last() - operator[](scalarList::size()-2)); + } + #ifdef FULLDEBUG checkIndex(i); #endif - return (operator[](i+1) + operator[](i)); + return 0.5*(operator[](i+1) + operator[](i)); +} + + +inline const Foam::scalar& +Foam::PDRblock::location::clip(const scalar& val) const +{ + if (scalarList::size()) + { + if (val < first()) + { + return first(); + } + else if (last() < val) + { + return last(); + } + } + + return val; // Pass-through } @@ -94,6 +141,12 @@ Foam::PDRblock::grid() const } +inline const Foam::scalar& Foam::PDRblock::minEdgeLen() const +{ + return minEdgeLen_; +} + + inline const Foam::boundBox& Foam::PDRblock::bounds() const { return bounds_; diff --git a/src/mesh/blockMesh/PDRblockMesh/PDRblockLocation.C b/src/mesh/blockMesh/PDRblockMesh/PDRblockLocation.C new file mode 100644 index 0000000000..ca92808d83 --- /dev/null +++ b/src/mesh/blockMesh/PDRblockMesh/PDRblockLocation.C @@ -0,0 +1,108 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2019 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +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 "PDRblock.H" +#include "ListOps.H" + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +Foam::label Foam::PDRblock::location::findCell(const scalar p) const +{ + if (scalarList::empty()) + { + return -1; + } + else if (equal(p, first())) + { + return 0; + } + else if (equal(p, last())) + { + return nCells()-1; + } + else if (p < first() || p > last()) + { + // The point is out-of-bounds + return -1; + } + + // Binary search, finds lower index and thus corresponds to the + // cell in which the point is found + return findLower(*this, p); +} + + +Foam::label Foam::PDRblock::location::findIndex +( + const scalar p, + const scalar tol +) const +{ + if (scalarList::empty()) + { + return -1; + } + else if (Foam::mag(p - first()) <= tol) + { + return 0; + } + else if (Foam::mag(p - last()) <= tol) + { + return scalarList::size()-1; + } + else if (p < first() || p > last()) + { + // The point is out-of-bounds + return -1; + } + + // Linear search + label i = 0; + scalar delta = GREAT; + + for (const scalar& val : *this) + { + const scalar diff = mag(p - val); + + if (diff <= tol) + { + return i; + } + else if (delta < diff) + { + // Moving further away + break; + } + + delta = diff; + ++i; + } + + // This point is within bounds, but not near a grid-point + return -2; +} + + +// ************************************************************************* // From e998e9fdfd6328ec7552fc291e2ab48ec6eba301 Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Tue, 26 Mar 2019 07:59:44 +0100 Subject: [PATCH 2/7] STYLE: avoid nullptr when writing fan RPM --- .../swirlFanVelocity/swirlFanVelocityFvPatchField.C | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/finiteVolume/fields/fvPatchFields/derived/swirlFanVelocity/swirlFanVelocityFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/derived/swirlFanVelocity/swirlFanVelocityFvPatchField.C index 3d0c0f9fd2..ede79590bf 100644 --- a/src/finiteVolume/fields/fvPatchFields/derived/swirlFanVelocity/swirlFanVelocityFvPatchField.C +++ b/src/finiteVolume/fields/fvPatchFields/derived/swirlFanVelocity/swirlFanVelocityFvPatchField.C @@ -107,7 +107,6 @@ void Foam::swirlFanVelocityFvPatchField::calcFanJump() } - // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // Foam::swirlFanVelocityFvPatchField::swirlFanVelocityFvPatchField @@ -156,7 +155,6 @@ Foam::swirlFanVelocityFvPatchField::swirlFanVelocityFvPatchField this->cyclicPatch().owner() ? Function1::New("rpm", dict) : nullptr - ), rEff_(dict.lookupOrDefault("rEff", 0)), fanEff_(dict.lookupOrDefault("fanEff", 1)), @@ -248,7 +246,11 @@ void Foam::swirlFanVelocityFvPatchField::write(Ostream& os) const os.writeEntryIfDifferent("p", "p", pName_); os.writeEntryIfDifferent("rho", "rho", rhoName_); os.writeEntry("origin", origin_); - rpm_->writeData(os); + + if (rpm_) + { + rpm_->writeData(os); + } os.writeEntryIfDifferent("rEff", 0.0, rEff_); os.writeEntryIfDifferent("useRealRadius", false, useRealRadius_); From c44b46d9fb4709684347819231125d712e344e2f Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Tue, 26 Mar 2019 08:17:53 +0100 Subject: [PATCH 3/7] STYLE: minor adjustments for fan tables (#1229) --- .../functions/Function1/Table/TableBase.H | 5 +---- .../functions/Function1/TableFile/TableFile.C | 13 +++---------- .../functions/Function1/TableFile/TableFile.H | 14 +++++++------- .../fvPatchFields/derived/fan/fanFvPatchField.H | 2 +- .../derived/uniformJump/uniformJumpFvPatchField.C | 1 + .../derived/uniformJump/uniformJumpFvPatchField.H | 2 +- 6 files changed, 14 insertions(+), 23 deletions(-) diff --git a/src/OpenFOAM/primitives/functions/Function1/Table/TableBase.H b/src/OpenFOAM/primitives/functions/Function1/Table/TableBase.H index 86a2f8f248..8a2686545f 100644 --- a/src/OpenFOAM/primitives/functions/Function1/Table/TableBase.H +++ b/src/OpenFOAM/primitives/functions/Function1/Table/TableBase.H @@ -62,7 +62,7 @@ class TableBase { protected: - // Protected data + // Protected Data //- Table name const word name_; @@ -93,9 +93,6 @@ protected: //- Return (demand driven) interpolator const interpolationWeights& interpolator() const; - -private: - //- No copy assignment void operator=(const TableBase&) = delete; diff --git a/src/OpenFOAM/primitives/functions/Function1/TableFile/TableFile.C b/src/OpenFOAM/primitives/functions/Function1/TableFile/TableFile.C index 53f0e82676..d7ff3921b3 100644 --- a/src/OpenFOAM/primitives/functions/Function1/TableFile/TableFile.C +++ b/src/OpenFOAM/primitives/functions/Function1/TableFile/TableFile.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2016-2017 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2016-2019 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- | Copyright (C) 2011-2017 OpenFOAM Foundation @@ -37,12 +37,12 @@ Foam::Function1Types::TableFile::TableFile ) : TableBase(entryName, dict), - fName_("none") + fName_() { dict.readEntry("file", fName_); fileName expandedFile(fName_); - //IFstream is(expandedFile.expand()); + autoPtr isPtr(fileHandler().NewIFstream(expandedFile.expand())); ISstream& is = isPtr(); @@ -66,13 +66,6 @@ Foam::Function1Types::TableFile::TableFile(const TableFile& tbl) {} -// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // - -template -Foam::Function1Types::TableFile::~TableFile() -{} - - // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // template diff --git a/src/OpenFOAM/primitives/functions/Function1/TableFile/TableFile.H b/src/OpenFOAM/primitives/functions/Function1/TableFile/TableFile.H index f7b1ce9ca8..485c98dac0 100644 --- a/src/OpenFOAM/primitives/functions/Function1/TableFile/TableFile.H +++ b/src/OpenFOAM/primitives/functions/Function1/TableFile/TableFile.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | + \\ / A nd | Copyright (C) 2019 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- | Copyright (C) 2011-2017 OpenFOAM Foundation @@ -27,7 +27,7 @@ Class Foam::Function1Types::TableFile Description - Templated table container function where data is read from file. + Templated table container function where data are read from file. Usage: \verbatim @@ -40,8 +40,8 @@ Description } \endverbatim - Data is stored as a list of Tuple2's. First column is always stored as - scalar entries. Data is read in the form, e.g. for an entry \ + Data are stored as a list of Tuple2's. First column is always stored as + scalar entries. Data are read in the form, e.g. for an entry \ that is (scalar, vector): \verbatim ( @@ -77,7 +77,7 @@ class TableFile : public TableBase { - // Private data + // Private Data //- File name for csv table (optional) fileName fName_; @@ -97,7 +97,7 @@ public: // Constructors - //- Construct from entry name and Istream + //- Construct from entry name and "file" found in dictionary TableFile(const word& entryName, const dictionary& dict); //- Copy constructor @@ -105,7 +105,7 @@ public: //- Destructor - virtual ~TableFile(); + virtual ~TableFile() = default; // I/O diff --git a/src/finiteVolume/fields/fvPatchFields/derived/fan/fanFvPatchField.H b/src/finiteVolume/fields/fvPatchFields/derived/fan/fanFvPatchField.H index 11d86e338a..06503f63a6 100644 --- a/src/finiteVolume/fields/fvPatchFields/derived/fan/fanFvPatchField.H +++ b/src/finiteVolume/fields/fvPatchFields/derived/fan/fanFvPatchField.H @@ -87,7 +87,7 @@ Usage componentColumns 1(1); separator ","; mergeSeparators no; - file "/pressureVsU"; + file "/UvsPressure"; } value uniform 0; } diff --git a/src/finiteVolume/fields/fvPatchFields/derived/uniformJump/uniformJumpFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/derived/uniformJump/uniformJumpFvPatchField.C index e5d5862663..0c065ca027 100644 --- a/src/finiteVolume/fields/fvPatchFields/derived/uniformJump/uniformJumpFvPatchField.C +++ b/src/finiteVolume/fields/fvPatchFields/derived/uniformJump/uniformJumpFvPatchField.C @@ -131,6 +131,7 @@ template void Foam::uniformJumpFvPatchField::write(Ostream& os) const { fixedJumpFvPatchField::write(os); + if (this->cyclicPatch().owner()) { jumpTable_->writeData(os); diff --git a/src/finiteVolume/fields/fvPatchFields/derived/uniformJump/uniformJumpFvPatchField.H b/src/finiteVolume/fields/fvPatchFields/derived/uniformJump/uniformJumpFvPatchField.H index 6f455e79d6..9c3576e740 100644 --- a/src/finiteVolume/fields/fvPatchFields/derived/uniformJump/uniformJumpFvPatchField.H +++ b/src/finiteVolume/fields/fvPatchFields/derived/uniformJump/uniformJumpFvPatchField.H @@ -94,7 +94,7 @@ protected: // Protected data - //- "jump" table + //- The "jump" table autoPtr> jumpTable_; From 21caf7c5f9102253c51a358ff6e05654af40e8a9 Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Tue, 26 Mar 2019 08:27:33 +0100 Subject: [PATCH 4/7] STYLE: add 'coeffs' to annotated decomposeParDict --- etc/caseDicts/annotated/decomposeParDict | 28 ++++++++++++++---------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/etc/caseDicts/annotated/decomposeParDict b/etc/caseDicts/annotated/decomposeParDict index 2b10b7b053..6143a89ab9 100644 --- a/etc/caseDicts/annotated/decomposeParDict +++ b/etc/caseDicts/annotated/decomposeParDict @@ -53,11 +53,10 @@ regions } -// Coefficients for the decomposition method are either as a -// general "coeffs" dictionary or method-specific "Coeffs". +// Coefficients for the decomposition method are either as a general +// "coeffs" dictionary or method-specific "Coeffs". // For multiLevel, using multiLevelCoeffs only. - multiLevelCoeffs { // multiLevel decomposition methods to apply in turn. @@ -70,12 +69,12 @@ multiLevelCoeffs level0 { numberOfSubdomains 16; - method scotch; + method scotch; } level1 { numberOfSubdomains 2; - method scotch; + method scotch; coeffs { n (2 1 1); @@ -85,8 +84,8 @@ multiLevelCoeffs level2 { numberOfSubdomains 8; - // method simple; - method scotch; + // method simple; + method scotch; } } @@ -107,17 +106,22 @@ multiLevelCoeffs // Other example coefficients +coeffs +{ + n (2 1 1); +} + simpleCoeffs { - n (2 1 1); - // delta 0.001; //< default value = 0.001 + n (2 1 1); + // delta 0.001; //< default value = 0.001 } hierarchicalCoeffs { - n (1 2 1); - // delta 0.001; //< default value = 0.001 - // order xyz; //< default order = xyz + n (1 2 1); + // delta 0.001; //< default value = 0.001 + // order xyz; //< default order = xyz } metisCoeffs From 154d1f001b456112e28d6491c5cae993ae3a0a99 Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Tue, 26 Mar 2019 09:16:57 +0100 Subject: [PATCH 5/7] ENH: improve findInstance handling of negative times (#1112) - normally findInstance will 'bottom out' with the constant directory while doing its reverse time search. This mechanism however fails when searching for negative start values (if there are none in the list). Add additional logic for this so that constant will also be used in these situations. Note: to have decomposePar work for all times, may need the -constant option to trigger the proper time list. --- .../fileOperation/fileOperation.C | 130 ++++++++---------- .../XiEngineFoam/kivaTest/Allrun-parallel | 13 ++ .../kivaTest/system/decomposeParDict | 27 ++++ 3 files changed, 99 insertions(+), 71 deletions(-) create mode 100755 tutorials/combustion/XiEngineFoam/kivaTest/Allrun-parallel create mode 100644 tutorials/combustion/XiEngineFoam/kivaTest/system/decomposeParDict diff --git a/src/OpenFOAM/global/fileOperations/fileOperation/fileOperation.C b/src/OpenFOAM/global/fileOperations/fileOperation/fileOperation.C index 21479775f5..1c4e484d50 100644 --- a/src/OpenFOAM/global/fileOperations/fileOperation/fileOperation.C +++ b/src/OpenFOAM/global/fileOperations/fileOperation/fileOperation.C @@ -104,51 +104,51 @@ Foam::instantList Foam::fileOperation::sortTimes ) { // Initialise instant list - instantList Times(dirEntries.size() + 1); + instantList times(dirEntries.size() + 1); label nTimes = 0; // Check for "constant" bool haveConstant = false; - forAll(dirEntries, i) + for (const fileName& dirName : dirEntries) { - if (dirEntries[i] == constantName) + if (dirName == constantName) { - Times[nTimes].value() = 0; - Times[nTimes].name() = dirEntries[i]; - nTimes++; haveConstant = true; + times[nTimes].value() = 0; + times[nTimes].name() = constantName; + ++nTimes; break; } } // Read and parse all the entries in the directory - forAll(dirEntries, i) + for (const fileName& dirName : dirEntries) { scalar timeValue; - if (readScalar(dirEntries[i], timeValue)) + if (readScalar(dirName, timeValue)) { - Times[nTimes].value() = timeValue; - Times[nTimes].name() = dirEntries[i]; - nTimes++; + times[nTimes].value() = timeValue; + times[nTimes].name() = dirName; + ++nTimes; } } // Reset the length of the times list - Times.setSize(nTimes); + times.setSize(nTimes); if (haveConstant) { if (nTimes > 2) { - std::sort(&Times[1], Times.end(), instant::less()); + std::sort(×[1], times.end(), instant::less()); } } else if (nTimes > 1) { - std::sort(&Times[0], Times.end(), instant::less()); + std::sort(×[0], times.end(), instant::less()); } - return Times; + return times; } @@ -161,15 +161,15 @@ void Foam::fileOperation::mergeTimes { if (extraTimes.size()) { - bool haveConstant = + const bool haveConstant = ( - times.size() > 0 + times.size() && times[0].name() == constantName ); - bool haveExtraConstant = + const bool haveExtraConstant = ( - extraTimes.size() > 0 + extraTimes.size() && extraTimes[0].name() == constantName ); @@ -228,9 +228,7 @@ void Foam::fileOperation::mergeTimes bool Foam::fileOperation::isFileOrDir(const bool isFile, const fileName& f) { - return - (isFile && Foam::isFile(f)) - || (!isFile && Foam::isDir(f)); + return (isFile ? Foam::isFile(f) : Foam::isDir(f)); } @@ -431,10 +429,8 @@ Foam::autoPtr Foam::fileOperation::New bool verbose ) { - if (debug) - { - InfoInFunction << "Constructing fileHandler" << endl; - } + DebugInFunction + << "Constructing fileHandler" << endl; auto cstrIter = wordConstructorTablePtr_->cfind(handlerType); @@ -570,14 +566,12 @@ Foam::fileName Foam::fileOperation::filePath(const fileName& fName) const } return fName; } - else + + if (debug) { - if (debug) - { - Pout<< "fileOperation::filePath : Not found" << endl; - } - return fileName::null; + Pout<< "fileOperation::filePath : Not found" << endl; } + return fileName::null; } @@ -755,13 +749,10 @@ Foam::IOobject Foam::fileOperation::findInstance if (exists(io)) { - if (debug) - { - InfoInFunction - << "Found exact match for \"" << io.name() - << "\" in " << io.instance()/io.local() - << endl; - } + DebugInFunction + << "Found exact match for \"" << io.name() + << "\" in " << io.instance()/io.local() + << endl; return io; } @@ -770,9 +761,9 @@ Foam::IOobject Foam::fileOperation::findInstance // closest to and lower than current time instantList ts = time.times(); - label instanceI; + label instanceI = ts.size()-1; - for (instanceI = ts.size()-1; instanceI >= 0; --instanceI) + for (; instanceI >= 0; --instanceI) { if (ts[instanceI].value() <= startValue) { @@ -780,7 +771,7 @@ Foam::IOobject Foam::fileOperation::findInstance } } - // continue searching from here + // Continue searching from here for (; instanceI >= 0; --instanceI) { // Shortcut: if actual directory is the timeName we've already tested it @@ -796,13 +787,10 @@ Foam::IOobject Foam::fileOperation::findInstance io.instance() = ts[instanceI].name(); if (exists(io)) { - if (debug) - { - InfoInFunction - << "Found exact match for \"" << io.name() - << "\" in " << io.instance()/io.local() - << endl; - } + DebugInFunction + << "Found exact match for \"" << io.name() + << "\" in " << io.instance()/io.local() + << endl; return io; } @@ -810,11 +798,8 @@ Foam::IOobject Foam::fileOperation::findInstance // Check if hit minimum instance if (ts[instanceI].name() == stopInstance) { - if (debug) - { - InfoInFunction - << "Hit stopInstance " << stopInstance << endl; - } + DebugInFunction + << "Hit stopInstance " << stopInstance << endl; if ( @@ -845,27 +830,30 @@ Foam::IOobject Foam::fileOperation::findInstance } } - // times() usually already includes the constant() so would have been - // checked above. Re-test if - // - times() is empty. Sometimes this can happen (e.g. decomposePar with - // collated) - // - times()[0] is not constant - if (!ts.size() || ts[0].name() != time.constant()) - { - // Note. This needs to be a hard-coded constant, rather than the - // constant function of the time, because the latter points to - // the case constant directory in parallel cases + // Times usually already includes 'constant' so would have been checked + // above. + // However, re-test under these conditions: + // - Times is empty. + // Sometimes this can happen (eg, decomposePar with collated) + // - Times[0] is not constant + // - The startValue is negative (eg, kivaTest). + // This plays havoc with the reverse search, causing it to miss 'constant' + if + ( + ts.empty() + || ts.first().name() != time.constant() + || startValue < 0 + ) + { io.instance() = time.constant(); if (exists(io)) { - if (debug) - { - InfoInFunction - << "Found constant match for \"" << io.name() - << "\" in " << io.instance()/io.local() - << endl; - } + DebugInFunction + << "Found constant match for \"" << io.name() + << "\" in " << io.instance()/io.local() + << endl; + return io; } } diff --git a/tutorials/combustion/XiEngineFoam/kivaTest/Allrun-parallel b/tutorials/combustion/XiEngineFoam/kivaTest/Allrun-parallel new file mode 100755 index 0000000000..2f1caf98b5 --- /dev/null +++ b/tutorials/combustion/XiEngineFoam/kivaTest/Allrun-parallel @@ -0,0 +1,13 @@ +#!/bin/sh +cd ${0%/*} || exit 1 # Run from this directory +. $WM_PROJECT_DIR/bin/tools/RunFunctions # Tutorial run functions + +runApplication kivaToFoam -file otape17 + +runApplication decomposePar + +runParallel $(getApplication) + +runApplication reconstructPar + +#------------------------------------------------------------------------------ diff --git a/tutorials/combustion/XiEngineFoam/kivaTest/system/decomposeParDict b/tutorials/combustion/XiEngineFoam/kivaTest/system/decomposeParDict new file mode 100644 index 0000000000..c7a4a538a1 --- /dev/null +++ b/tutorials/combustion/XiEngineFoam/kivaTest/system/decomposeParDict @@ -0,0 +1,27 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v1812 | +| \\ / A nd | Web: www.OpenFOAM.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object decomposeParDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +numberOfSubdomains 4; + +method hierarchical; + +coeffs +{ + n (2 2 1); +} + + +// ************************************************************************* // From 4547796ae9118a0e3b6a3823dc776fb1488a4984 Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Tue, 26 Mar 2019 09:42:27 +0100 Subject: [PATCH 6/7] BUG: dereference invalid autoPtr in XiEngineFoam (fixes #1250) --- .../XiFoam/XiEngineFoam/logSummary.H | 35 +++++++++++-------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/applications/solvers/combustion/XiFoam/XiEngineFoam/logSummary.H b/applications/solvers/combustion/XiFoam/XiEngineFoam/logSummary.H index 1946f38da8..d18024e65d 100644 --- a/applications/solvers/combustion/XiFoam/XiEngineFoam/logSummary.H +++ b/applications/solvers/combustion/XiFoam/XiEngineFoam/logSummary.H @@ -1,15 +1,22 @@ -Info<< "Mean pressure:" << p.weightedAverage(mesh.V()).value() << endl; -Info<< "Mean temperature:" << thermo.T().weightedAverage(mesh.V()).value() - << endl; -Info<< "Mean u':" - << (sqrt((2.0/3.0)*turbulence->k()))().weightedAverage(mesh.V()).value() - << endl; +{ + const scalar meanP = p.weightedAverage(mesh.V()).value(); + const scalar meanT = thermo.T().weightedAverage(mesh.V()).value(); + const scalar meanUp = + (sqrt((2.0/3.0)*turbulence->k()))().weightedAverage(mesh.V()).value(); + const scalar meanB = b.weightedAverage(mesh.V()).value(); -logSummaryFile() - << runTime.theta() << tab - << p.weightedAverage(mesh.V()).value() << tab - << thermo.T().weightedAverage(mesh.V()).value() << tab - << (sqrt((2.0/3.0)*turbulence->k()))().weightedAverage(mesh.V()).value() - << tab - << 1 - b.weightedAverage(mesh.V()).value() - << endl; + Info<< "Mean pressure:" << meanP << nl + << "Mean temperature:" << meanT << nl + << "Mean u':" << meanUp << endl; + + if (Pstream::master()) + { + logSummaryFile() + << runTime.theta() << tab + << meanP << tab + << meanT << tab + << meanUp << tab + << 1 - meanB + << endl; + } +} From 6297f7b0fd0bed245b8d24d7e17c5243225edf1c Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Mon, 25 Feb 2019 18:40:35 +0100 Subject: [PATCH 7/7] ENH: use cellPoint interpolation directly for surfaceFieldValue (#1212) - prior to sampledSurface supporting different interpolation schemes a workaround means was used to simulate cellPoint -> face interpolation, with averaging of vertex interpolation. We instead now use cellPoint interpolation directly for the face values when 'interpolate=true'. --- .../surfaceFieldValue/surfaceFieldValue.H | 2 +- .../surfaceFieldValueTemplates.C | 19 +------------------ 2 files changed, 2 insertions(+), 19 deletions(-) diff --git a/src/functionObjects/field/fieldValues/surfaceFieldValue/surfaceFieldValue.H b/src/functionObjects/field/fieldValues/surfaceFieldValue/surfaceFieldValue.H index b79fa5a79d..2e29dbef9b 100644 --- a/src/functionObjects/field/fieldValues/surfaceFieldValue/surfaceFieldValue.H +++ b/src/functionObjects/field/fieldValues/surfaceFieldValue/surfaceFieldValue.H @@ -211,7 +211,7 @@ class surfaceFieldValue { public: - // Public data types + // Public Data Types //- Region type enumeration enum regionTypes diff --git a/src/functionObjects/field/fieldValues/surfaceFieldValue/surfaceFieldValueTemplates.C b/src/functionObjects/field/fieldValues/surfaceFieldValue/surfaceFieldValueTemplates.C index fbb066cc40..7eb1abb57e 100644 --- a/src/functionObjects/field/fieldValues/surfaceFieldValue/surfaceFieldValueTemplates.C +++ b/src/functionObjects/field/fieldValues/surfaceFieldValue/surfaceFieldValueTemplates.C @@ -98,25 +98,8 @@ Foam::functionObjects::fieldValues::surfaceFieldValue::getFieldValues if (sampledPtr_().interpolate()) { const interpolationCellPoint interp(fld); - tmp> tintFld(sampledPtr_().interpolate(interp)); - const Field& intFld = tintFld(); - // Average - const faceList& faces = sampledPtr_().faces(); - auto tavg = tmp>::New(faces.size(), Zero); - auto& avg = tavg.ref(); - - forAll(faces, facei) - { - const face& f = faces[facei]; - for (const label labi : f) - { - avg[facei] += intFld[labi]; - } - avg[facei] /= f.size(); - } - - return tavg; + return sampledPtr_().sample(interp); } else {