From 96763bb06bcd1c235c2966343b9afde2aa85c0b6 Mon Sep 17 00:00:00 2001 From: Andrew Heather <> Date: Fri, 11 Sep 2020 20:33:06 +0100 Subject: [PATCH] ENH: Added optional limits to Function1 (#1924) To apply limits to the input values, use the dictionary format to include the optional keywords 'minLimit' and/or 'maxLimit', e.g. limitedPolyTest polynomial; limitedPolyTestCoeffs { limitedPolyTest coeffs ( (5 1) (-2 2) (-2 3) (1 4) ); minLimit 0.4; maxLimit 1.4; } limitedTableFileTest tableFile; limitedTableFileTestCoeffs { file "<system>/fanCurve.txt"; minLimit 0.4; maxLimit 1.4; } --- .../Function1/Function1Expression.C | 2 +- .../functions/Function1/Function1/Function1.C | 22 ++++++++++ .../functions/Function1/Function1/Function1.H | 8 ++++ .../Function1/Function1/function1Base.C | 37 ++++++++++++++-- .../Function1/Function1/function1Base.H | 9 ++++ .../PolynomialEntry/PolynomialEntry.C | 13 ++++-- .../PolynomialEntry/PolynomialEntry.H | 7 +++ .../functions/Function1/Scale/ScaleI.H | 5 ++- .../functions/Function1/Sine/SineI.H | 12 ++++-- .../functions/Function1/Table/TableBase.C | 43 ++++++++++++------- .../functions/Function1/Table/TableBase.H | 2 +- .../halfCosineRamp/halfCosineRampI.H | 5 ++- .../Function1/linearRamp/linearRampI.H | 3 +- .../Function1/quadraticRamp/quadraticRampI.H | 3 +- .../quarterCosineRamp/quarterCosineRampI.H | 4 +- .../quarterSineRamp/quarterSineRampI.H | 3 +- .../functions/Function1/step/stepFunctionI.H | 4 +- 17 files changed, 147 insertions(+), 35 deletions(-) diff --git a/src/OpenFOAM/expressions/Function1/Function1Expression.C b/src/OpenFOAM/expressions/Function1/Function1Expression.C index 2575e0cb014..82e0cc9fd79 100644 --- a/src/OpenFOAM/expressions/Function1/Function1Expression.C +++ b/src/OpenFOAM/expressions/Function1/Function1Expression.C @@ -86,7 +86,7 @@ Type Foam::Function1Types::Function1Expression<Type>::value // Expression evaluation driver_.clearVariables(); - driver_.setArgument(x); + driver_.setArgument(this->limitValue(x)); driver_.parse(this->valueExpr_); diff --git a/src/OpenFOAM/primitives/functions/Function1/Function1/Function1.C b/src/OpenFOAM/primitives/functions/Function1/Function1/Function1.C index f635078a468..38185c12840 100644 --- a/src/OpenFOAM/primitives/functions/Function1/Function1/Function1.C +++ b/src/OpenFOAM/primitives/functions/Function1/Function1/Function1.C @@ -31,6 +31,28 @@ License // Required by clang 5 for correct instantiation of Function1::New #include "Constant.H" +// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // + +template<class Type> +void Foam::Function1<Type>::addLimitedAreaToSum +( + const scalar x1, + const scalar x2, + Type& sum +) const +{ + if (x1 < minLimit_) + { + sum += (min(minLimit_, x2) - x1)*this->value(minLimit_); + } + + if (x2 > maxLimit_) + { + sum += (x2 - max(maxLimit_, x1))*this->value(maxLimit_); + } +} + + // * * * * * * * * * * * * * * * * Constructor * * * * * * * * * * * * * * * // template<class Type> diff --git a/src/OpenFOAM/primitives/functions/Function1/Function1/Function1.H b/src/OpenFOAM/primitives/functions/Function1/Function1/Function1.H index 5ff592788bc..465aa714947 100644 --- a/src/OpenFOAM/primitives/functions/Function1/Function1/Function1.H +++ b/src/OpenFOAM/primitives/functions/Function1/Function1/Function1.H @@ -116,6 +116,14 @@ protected: //- No copy assignment void operator=(const Function1<Type>&) = delete; + //- Helper function for integrate() function to add limited contribution + void addLimitedAreaToSum + ( + const scalar x1, + const scalar x2, + Type& sum + ) const; + public: diff --git a/src/OpenFOAM/primitives/functions/Function1/Function1/function1Base.C b/src/OpenFOAM/primitives/functions/Function1/Function1/function1Base.C index c4a6e0a1940..423c4a2611c 100644 --- a/src/OpenFOAM/primitives/functions/Function1/Function1/function1Base.C +++ b/src/OpenFOAM/primitives/functions/Function1/Function1/function1Base.C @@ -33,7 +33,9 @@ License Foam::function1Base::function1Base(const word& entryName) : refCount(), - name_(entryName) + name_(entryName), + minLimit_(-GREAT), + maxLimit_(GREAT) {} @@ -44,21 +46,48 @@ Foam::function1Base::function1Base ) : refCount(), - name_(entryName) + name_(entryName), + minLimit_(dict.getOrDefault<scalar>("minLimit", -GREAT)), + maxLimit_(dict.getOrDefault<scalar>("maxLimit", GREAT)) {} Foam::function1Base::function1Base(const function1Base& rhs) : refCount(), - name_(rhs.name_) + name_(rhs.name_), + minLimit_(rhs.minLimit_), + maxLimit_(rhs.maxLimit_) {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // void Foam::function1Base::convertTimeBase(const Time& t) -{} +{ + minLimit_ = t.userTimeToTime(minLimit_); + maxLimit_ = t.userTimeToTime(maxLimit_); +} + + +Foam::scalar Foam::function1Base::limitValue(const scalar x) const +{ + return min(max(minLimit_, x), maxLimit_); +} + + +// TBD +// void Foam::function1Base::writeEntries(Ostream& os) const +// { +// if (minLimit_ > -ROOTGREAT) +// { +// os.writeEntry("minLimit", minLimit_); +// } +// if (maxLimit_ < ROOTGREAT) +// { +// os.writeEntry("maxLimit", maxLimit_); +// } +// } // ************************************************************************* // diff --git a/src/OpenFOAM/primitives/functions/Function1/Function1/function1Base.H b/src/OpenFOAM/primitives/functions/Function1/Function1/function1Base.H index 4aa9bf68ea2..462882af019 100644 --- a/src/OpenFOAM/primitives/functions/Function1/Function1/function1Base.H +++ b/src/OpenFOAM/primitives/functions/Function1/Function1/function1Base.H @@ -67,6 +67,12 @@ protected: //- Name of entry const word name_; + //- Optional minimum limit (x) + scalar minLimit_; + + //- Optional maximum limit (x) + scalar maxLimit_; + // Protected Member Functions @@ -107,6 +113,9 @@ public: //- Convert time virtual void convertTimeBase(const Time& t); + + //- Apply min|max limit to the input value + virtual scalar limitValue(const scalar x) const; }; diff --git a/src/OpenFOAM/primitives/functions/Function1/PolynomialEntry/PolynomialEntry.C b/src/OpenFOAM/primitives/functions/Function1/PolynomialEntry/PolynomialEntry.C index a2197035569..b6e29177411 100644 --- a/src/OpenFOAM/primitives/functions/Function1/PolynomialEntry/PolynomialEntry.C +++ b/src/OpenFOAM/primitives/functions/Function1/PolynomialEntry/PolynomialEntry.C @@ -144,13 +144,15 @@ void Foam::Function1Types::Polynomial<Type>::convertTimeBase(const Time& t) template<class Type> Type Foam::Function1Types::Polynomial<Type>::value(const scalar x) const { + const scalar xlim = this->limitValue(x); + Type y(Zero); forAll(coeffs_, i) { y += cmptMultiply ( coeffs_[i].first(), - cmptPow(pTraits<Type>::one*x, coeffs_[i].second()) + cmptPow(pTraits<Type>::one*xlim, coeffs_[i].second()) ); } @@ -167,6 +169,11 @@ Type Foam::Function1Types::Polynomial<Type>::integrate { Type intx(Zero); + this->addLimitedAreaToSum(x1, x2, intx); + + const scalar x1lim = this->limitValue(x1); + const scalar x2lim = this->limitValue(x2); + if (canIntegrate_) { forAll(coeffs_, i) @@ -180,12 +187,12 @@ Type Foam::Function1Types::Polynomial<Type>::integrate ), cmptPow ( - pTraits<Type>::one*x2, + pTraits<Type>::one*x2lim, coeffs_[i].second() + pTraits<Type>::one ) - cmptPow ( - pTraits<Type>::one*x1, + pTraits<Type>::one*x1lim, coeffs_[i].second() + pTraits<Type>::one ) ); diff --git a/src/OpenFOAM/primitives/functions/Function1/PolynomialEntry/PolynomialEntry.H b/src/OpenFOAM/primitives/functions/Function1/PolynomialEntry/PolynomialEntry.H index 06d778c0c6c..5f41d7ab46f 100644 --- a/src/OpenFOAM/primitives/functions/Function1/PolynomialEntry/PolynomialEntry.H +++ b/src/OpenFOAM/primitives/functions/Function1/PolynomialEntry/PolynomialEntry.H @@ -6,6 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2017 OpenFOAM Foundation + Copyright (C) 2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -103,6 +104,12 @@ public: //- Copy constructor explicit Polynomial(const Polynomial& poly); + //- Construct and return a clone + virtual tmp<Function1<Type>> clone() const + { + return tmp<Function1<Type>>(new Polynomial<Type>(*this)); + } + //- Destructor virtual ~Polynomial() = default; diff --git a/src/OpenFOAM/primitives/functions/Function1/Scale/ScaleI.H b/src/OpenFOAM/primitives/functions/Function1/Scale/ScaleI.H index fe201a48108..515307be29c 100644 --- a/src/OpenFOAM/primitives/functions/Function1/Scale/ScaleI.H +++ b/src/OpenFOAM/primitives/functions/Function1/Scale/ScaleI.H @@ -6,6 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2017 OpenFOAM Foundation + Copyright (C) 2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -32,7 +33,9 @@ License template<class Type> inline Type Foam::Function1Types::Scale<Type>::value(const scalar t) const { - return scale_->value(t)*value_->value(t); + const scalar tlim = this->limitValue(t); + + return scale_->value(tlim)*value_->value(tlim); } diff --git a/src/OpenFOAM/primitives/functions/Function1/Sine/SineI.H b/src/OpenFOAM/primitives/functions/Function1/Sine/SineI.H index be03d62ddce..722562c5c94 100644 --- a/src/OpenFOAM/primitives/functions/Function1/Sine/SineI.H +++ b/src/OpenFOAM/primitives/functions/Function1/Sine/SineI.H @@ -92,9 +92,11 @@ Foam::Function1Types::Sine<Type>::squareForm template<class Type> inline Type Foam::Function1Types::Sine<Type>::cosValue(const scalar t) const { + const scalar tlim = this->limitValue(t); + return ( - cosForm(t) * scale_->value(t) + level_->value(t) + cosForm(tlim) * scale_->value(tlim) + level_->value(tlim) ); } @@ -102,9 +104,11 @@ inline Type Foam::Function1Types::Sine<Type>::cosValue(const scalar t) const template<class Type> inline Type Foam::Function1Types::Sine<Type>::sinValue(const scalar t) const { + const scalar tlim = this->limitValue(t); + return ( - sinForm(t) * scale_->value(t) + level_->value(t) + sinForm(tlim) * scale_->value(tlim) + level_->value(tlim) ); } @@ -116,9 +120,11 @@ inline Type Foam::Function1Types::Sine<Type>::squareValue const scalar posFrac ) const { + const scalar tlim = this->limitValue(t); + return ( - squareForm(t, posFrac) * scale_->value(t) + level_->value(t) + squareForm(tlim, posFrac) * scale_->value(tlim) + level_->value(tlim) ); } diff --git a/src/OpenFOAM/primitives/functions/Function1/Table/TableBase.C b/src/OpenFOAM/primitives/functions/Function1/Table/TableBase.C index 8c1fdb25957..715df68417d 100644 --- a/src/OpenFOAM/primitives/functions/Function1/Table/TableBase.C +++ b/src/OpenFOAM/primitives/functions/Function1/Table/TableBase.C @@ -98,13 +98,6 @@ Foam::Function1Types::TableBase<Type>::TableBase(const TableBase<Type>& tbl) {} -// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // - -template<class Type> -Foam::Function1Types::TableBase<Type>::~TableBase() -{} - - // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // template<class Type> @@ -270,9 +263,11 @@ void Foam::Function1Types::TableBase<Type>::convertTimeBase(const Time& t) template<class Type> Type Foam::Function1Types::TableBase<Type>::value(const scalar x) const { - scalar xDash = x; + const scalar xlim = this->limitValue(x); + + scalar xDash = xlim; - if (checkMinBounds(x, xDash)) + if (checkMinBounds(xlim, xDash)) { return table_.first().second(); } @@ -286,7 +281,7 @@ Type Foam::Function1Types::TableBase<Type>::value(const scalar x) const interpolator().valueWeights(xDash, currentIndices_, currentWeights_); Type t = currentWeights_[0]*table_[currentIndices_[0]].second(); - for (label i = 1; i < currentIndices_.size(); i++) + for (label i = 1; i < currentIndices_.size(); ++i) { t += currentWeights_[i]*table_[currentIndices_[i]].second(); } @@ -302,15 +297,31 @@ Type Foam::Function1Types::TableBase<Type>::integrate const scalar x2 ) const { - // Use interpolator - interpolator().integrationWeights(x1, x2, currentIndices_, currentWeights_); + scalar x1lim = this->limitValue(x1); + scalar x2lim = this->limitValue(x2); - Type sum = currentWeights_[0]*table_[currentIndices_[0]].second(); - for (label i = 1; i < currentIndices_.size(); i++) + Type sum = Zero; + + if (mag(x2lim - x1lim) > ROOTVSMALL) { - sum += currentWeights_[i]*table_[currentIndices_[i]].second(); + // Use interpolator + interpolator().integrationWeights + ( + this->limitValue(x1), + this->limitValue(x2), + currentIndices_, + currentWeights_ + ); + + sum += currentWeights_[0]*table_[currentIndices_[0]].second(); + for (label i = 1; i < currentIndices_.size(); ++i) + { + sum += currentWeights_[i]*table_[currentIndices_[i]].second(); + } } + this->addLimitedAreaToSum(x1, x2, sum); + return sum; } @@ -323,7 +334,7 @@ Foam::tmp<Foam::scalarField> Foam::Function1Types::TableBase<Type>::x() const forAll(table_, i) { - fld[i] = table_[i].first(); + fld[i] = this->limitValue(table_[i].first()); } return tfld; diff --git a/src/OpenFOAM/primitives/functions/Function1/Table/TableBase.H b/src/OpenFOAM/primitives/functions/Function1/Table/TableBase.H index 82361382bd2..704230be74f 100644 --- a/src/OpenFOAM/primitives/functions/Function1/Table/TableBase.H +++ b/src/OpenFOAM/primitives/functions/Function1/Table/TableBase.H @@ -108,7 +108,7 @@ public: //- Destructor - virtual ~TableBase(); + virtual ~TableBase() = default; // Member Functions diff --git a/src/OpenFOAM/primitives/functions/Function1/halfCosineRamp/halfCosineRampI.H b/src/OpenFOAM/primitives/functions/Function1/halfCosineRamp/halfCosineRampI.H index 1f50e6c8680..641bacb6e02 100644 --- a/src/OpenFOAM/primitives/functions/Function1/halfCosineRamp/halfCosineRampI.H +++ b/src/OpenFOAM/primitives/functions/Function1/halfCosineRamp/halfCosineRampI.H @@ -6,6 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2017 OpenFOAM Foundation + Copyright (C) 2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -35,7 +36,9 @@ inline Foam::scalar Foam::Function1Types::halfCosineRamp::value const scalar t ) const { - return 0.5*(1 - cos(constant::mathematical::pi*linearRamp(t))); + return + 0.5 + *(1 - cos(constant::mathematical::pi*linearRamp(this->limitValue(t)))); } diff --git a/src/OpenFOAM/primitives/functions/Function1/linearRamp/linearRampI.H b/src/OpenFOAM/primitives/functions/Function1/linearRamp/linearRampI.H index 318323c3427..3670f60fe06 100644 --- a/src/OpenFOAM/primitives/functions/Function1/linearRamp/linearRampI.H +++ b/src/OpenFOAM/primitives/functions/Function1/linearRamp/linearRampI.H @@ -6,6 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2017 OpenFOAM Foundation + Copyright (C) 2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -34,7 +35,7 @@ inline Foam::scalar Foam::Function1Types::linearRamp::value const scalar t ) const { - return ramp::linearRamp(t); + return ramp::linearRamp(this->limitValue(t)); } diff --git a/src/OpenFOAM/primitives/functions/Function1/quadraticRamp/quadraticRampI.H b/src/OpenFOAM/primitives/functions/Function1/quadraticRamp/quadraticRampI.H index 14a850ac65f..f0b2ea02a52 100644 --- a/src/OpenFOAM/primitives/functions/Function1/quadraticRamp/quadraticRampI.H +++ b/src/OpenFOAM/primitives/functions/Function1/quadraticRamp/quadraticRampI.H @@ -6,6 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2017 OpenFOAM Foundation + Copyright (C) 2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -34,7 +35,7 @@ inline Foam::scalar Foam::Function1Types::quadraticRamp::value const scalar t ) const { - return sqr(linearRamp(t)); + return sqr(linearRamp(this->limitValue(t))); } diff --git a/src/OpenFOAM/primitives/functions/Function1/quarterCosineRamp/quarterCosineRampI.H b/src/OpenFOAM/primitives/functions/Function1/quarterCosineRamp/quarterCosineRampI.H index 4b5b2fabc5b..582e209cda5 100644 --- a/src/OpenFOAM/primitives/functions/Function1/quarterCosineRamp/quarterCosineRampI.H +++ b/src/OpenFOAM/primitives/functions/Function1/quarterCosineRamp/quarterCosineRampI.H @@ -6,6 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2017 OpenFOAM Foundation + Copyright (C) 2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -35,7 +36,8 @@ inline Foam::scalar Foam::Function1Types::quarterCosineRamp::value const scalar t ) const { - return 1 - cos(0.5*constant::mathematical::pi*linearRamp(t)); + return + 1 - cos(0.5*constant::mathematical::pi*linearRamp(this->limitValue(t))); } diff --git a/src/OpenFOAM/primitives/functions/Function1/quarterSineRamp/quarterSineRampI.H b/src/OpenFOAM/primitives/functions/Function1/quarterSineRamp/quarterSineRampI.H index ea7d9a9a49a..002482fd530 100644 --- a/src/OpenFOAM/primitives/functions/Function1/quarterSineRamp/quarterSineRampI.H +++ b/src/OpenFOAM/primitives/functions/Function1/quarterSineRamp/quarterSineRampI.H @@ -6,6 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2017 OpenFOAM Foundation + Copyright (C) 2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -35,7 +36,7 @@ inline Foam::scalar Foam::Function1Types::quarterSineRamp::value const scalar t ) const { - return sin(0.5*constant::mathematical::pi*linearRamp(t)); + return sin(0.5*constant::mathematical::pi*linearRamp(this->limitValue(t))); } diff --git a/src/OpenFOAM/primitives/functions/Function1/step/stepFunctionI.H b/src/OpenFOAM/primitives/functions/Function1/step/stepFunctionI.H index c3016813892..49850779287 100644 --- a/src/OpenFOAM/primitives/functions/Function1/step/stepFunctionI.H +++ b/src/OpenFOAM/primitives/functions/Function1/step/stepFunctionI.H @@ -34,7 +34,9 @@ inline Foam::scalar Foam::Function1Types::stepFunction::value const scalar t ) const { - if (t < start_ || t > start_ + duration_) + const scalar tlim = this->limitValue(t); + + if (tlim < start_ || tlim > start_ + duration_) { return 0; } -- GitLab