From ba66d36bfd7154227156dd8a99456630308c58f3 Mon Sep 17 00:00:00 2001 From: graham <g.macpherson@opencfd.co.uk> Date: Tue, 27 Jul 2010 12:55:01 +0100 Subject: [PATCH] ENH: rateOfChange function for interpolationTable. Creates linear slope only from low and high elements around the sample value, so rate will be discontinuous. Would be better with higher order gradient calculation. --- .../interpolationTable/interpolationTable.C | 164 +++++++++++++++++- .../interpolationTable/interpolationTable.H | 6 +- 2 files changed, 167 insertions(+), 3 deletions(-) diff --git a/src/OpenFOAM/interpolations/interpolationTable/interpolationTable.C b/src/OpenFOAM/interpolations/interpolationTable/interpolationTable.C index 2bdf04cce09..6699b6349b7 100644 --- a/src/OpenFOAM/interpolations/interpolationTable/interpolationTable.C +++ b/src/OpenFOAM/interpolations/interpolationTable/interpolationTable.C @@ -236,6 +236,166 @@ void Foam::interpolationTable<Type>::write(Ostream& os) const } +template<class Type> +Type Foam::interpolationTable<Type>::rateOfChange(const scalar value) const +{ + label n = this->size(); + + if (n <= 1) + { + // There are not enough entries to provide a rate of change + return 0; + } + + scalar minLimit = List<Tuple2<scalar, Type> >::operator[](0).first(); + scalar maxLimit = List<Tuple2<scalar, Type> >::operator[](n-1).first(); + scalar lookupValue = value; + + if (lookupValue < minLimit) + { + switch (boundsHandling_) + { + case interpolationTable::ERROR: + { + FatalErrorIn + ( + "Foam::interpolationTable<Type>::operator[]" + "(const scalar) const" + ) << "value (" << lookupValue << ") underflow" << nl + << exit(FatalError); + break; + } + case interpolationTable::WARN: + { + WarningIn + ( + "Foam::interpolationTable<Type>::operator[]" + "(const scalar) const" + ) << "value (" << lookupValue << ") underflow" << nl + << " Zero rate of change." + << endl; + // fall-through to 'CLAMP' + } + case interpolationTable::CLAMP: + { + return 0; + break; + } + case interpolationTable::REPEAT: + { + // adjust lookupValue to >= minLimit + while (lookupValue < minLimit) + { + lookupValue += maxLimit; + } + break; + } + } + } + else if (lookupValue >= maxLimit) + { + switch (boundsHandling_) + { + case interpolationTable::ERROR: + { + FatalErrorIn + ( + "Foam::interpolationTable<Type>::operator[]" + "(const label) const" + ) << "value (" << lookupValue << ") overflow" << nl + << exit(FatalError); + break; + } + case interpolationTable::WARN: + { + WarningIn + ( + "Foam::interpolationTable<Type>::operator[]" + "(const label) const" + ) << "value (" << lookupValue << ") overflow" << nl + << " Zero rate of change." + << endl; + // fall-through to 'CLAMP' + } + case interpolationTable::CLAMP: + { + return 0; + break; + } + case interpolationTable::REPEAT: + { + // adjust lookupValue <= maxLimit + while (lookupValue > maxLimit) + { + lookupValue -= maxLimit; + } + break; + } + } + } + + label lo = 0; + label hi = 0; + + // look for the correct range + for (label i = 0; i < n; ++i) + { + if (lookupValue >= List<Tuple2<scalar, Type> >::operator[](i).first()) + { + lo = hi = i; + } + else + { + hi = i; + break; + } + } + + if (lo == hi) + { + // we are at the end of the table - or there is only a single entry + return 0; + } + else if (hi == 0) + { + // this treatment should should only occur under these conditions: + // -> the 'REPEAT' treatment + // -> (0 <= value <= minLimit) + // -> minLimit > 0 + // Use the value at maxLimit as the value for value=0 + lo = n - 1; + + return + ( + ( + List<Tuple2<scalar, Type> >::operator[](hi).second() + - List<Tuple2<scalar, Type> >::operator[](lo).second() + ) + /( + List<Tuple2<scalar, Type> >::operator[](hi).first() + + minLimit + - List<Tuple2<scalar, Type> >::operator[](lo).first() + ) + ); + } + else + { + // normal rate of change + return + ( + ( + List<Tuple2<scalar, Type> >::operator[](hi).second() + - List<Tuple2<scalar, Type> >::operator[](lo).second() + ) + /( + List<Tuple2<scalar, Type> >::operator[](hi).first() + - List<Tuple2<scalar, Type> >::operator[](lo).first() + ) + ); + } +} + + // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // template<class Type> @@ -380,8 +540,8 @@ Type Foam::interpolationTable<Type>::operator()(const scalar value) const } case interpolationTable::REPEAT: { - // adjust lookupValue to >= 0 - while (lookupValue < 0) + // adjust lookupValue to >= minLimin + while (lookupValue < minLimit) { lookupValue += maxLimit; } diff --git a/src/OpenFOAM/interpolations/interpolationTable/interpolationTable.H b/src/OpenFOAM/interpolations/interpolationTable/interpolationTable.H index 300b045c79b..8ef701c4d1a 100644 --- a/src/OpenFOAM/interpolations/interpolationTable/interpolationTable.H +++ b/src/OpenFOAM/interpolations/interpolationTable/interpolationTable.H @@ -26,7 +26,7 @@ Class Description An interpolation/look-up table of scalar vs <Type> values. - The reference scalar values must be positive and monotonically increasing. + The reference scalar values must be monotonically increasing. The handling of out-of-bounds values depends on the current setting of @a outOfBounds. @@ -139,6 +139,10 @@ public: //- Write void write(Ostream& os) const; + //- Return the rate of change at the interpolation location + // for the give value + Type rateOfChange(const scalar) const; + // Member Operators -- GitLab