ENH: interpolationTable improvements

- reduce code duplication, support returning multiple interpolations
  as a Field
This commit is contained in:
Mark Olesen
2019-08-23 15:57:22 +02:00
committed by Andrew Heather
parent 784d3ad5d4
commit 87330972d8
7 changed files with 444 additions and 482 deletions

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2016 OpenCFD Ltd. Copyright (C) 2016-2019 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -47,7 +47,7 @@ void Foam::interpolation2DTable<Type>::readTable()
} }
// Check that the data are in ascending order // Check that the data are in ascending order
checkOrder(); check();
} }
@ -56,7 +56,7 @@ void Foam::interpolation2DTable<Type>::readTable()
template<class Type> template<class Type>
Foam::interpolation2DTable<Type>::interpolation2DTable() Foam::interpolation2DTable<Type>::interpolation2DTable()
: :
List<Tuple2<scalar, List<Tuple2<scalar, Type>>>>(), List<value_type>(),
bounding_(bounds::normalBounding::WARN), bounding_(bounds::normalBounding::WARN),
fileName_("fileNameIsUndefined"), fileName_("fileNameIsUndefined"),
reader_(nullptr) reader_(nullptr)
@ -71,7 +71,7 @@ Foam::interpolation2DTable<Type>::interpolation2DTable
const fileName& fName const fileName& fName
) )
: :
List<Tuple2<scalar, List<Tuple2<scalar, Type>>>>(values), List<value_type>(values),
bounding_(bounding), bounding_(bounding),
fileName_(fName), fileName_(fName),
reader_(nullptr) reader_(nullptr)
@ -81,7 +81,7 @@ Foam::interpolation2DTable<Type>::interpolation2DTable
template<class Type> template<class Type>
Foam::interpolation2DTable<Type>::interpolation2DTable(const fileName& fName) Foam::interpolation2DTable<Type>::interpolation2DTable(const fileName& fName)
: :
List<Tuple2<scalar, List<Tuple2<scalar, Type>>>>(), List<value_type>(),
bounding_(bounds::normalBounding::WARN), bounding_(bounds::normalBounding::WARN),
fileName_(fName), fileName_(fName),
reader_(new openFoamTableReader<Type>(dictionary())) reader_(new openFoamTableReader<Type>(dictionary()))
@ -93,7 +93,7 @@ Foam::interpolation2DTable<Type>::interpolation2DTable(const fileName& fName)
template<class Type> template<class Type>
Foam::interpolation2DTable<Type>::interpolation2DTable(const dictionary& dict) Foam::interpolation2DTable<Type>::interpolation2DTable(const dictionary& dict)
: :
List<Tuple2<scalar, List<Tuple2<scalar, Type>>>>(), List<value_type>(),
bounding_ bounding_
( (
bounds::normalBoundingNames.lookupOrDefault bounds::normalBoundingNames.lookupOrDefault
@ -104,7 +104,7 @@ Foam::interpolation2DTable<Type>::interpolation2DTable(const dictionary& dict)
true // Failsafe behaviour true // Failsafe behaviour
) )
), ),
fileName_(dict.lookup("file")), fileName_(dict.get<fileName>("file")),
reader_(tableReader<Type>::New(dict)) reader_(tableReader<Type>::New(dict))
{ {
readTable(); readTable();
@ -117,121 +117,28 @@ Foam::interpolation2DTable<Type>::interpolation2DTable
const interpolation2DTable& interpTable const interpolation2DTable& interpTable
) )
: :
List<Tuple2<scalar, List<Tuple2<scalar, Type>>>>(interpTable), List<value_type>(interpTable),
bounding_(interpTable.bounding_), bounding_(interpTable.bounding_),
fileName_(interpTable.fileName_), fileName_(interpTable.fileName_),
reader_(interpTable.reader_) // note: steals reader. Used in write(). reader_(interpTable.reader_) // note: steals reader. Used in write().
{} {}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type> template<class Type>
Type Foam::interpolation2DTable<Type>::interpolateValue Type Foam::interpolation2DTable<Type>::interpolateValue
( (
const List<Tuple2<scalar, Type>>& data, const List<Tuple2<scalar, Type>>& list,
const scalar lookupValue scalar lookupValue
) const ) const
{ {
const label n = data.size(); return interpolationTable<Type>::interpolateValue
(
const scalar minLimit = data.first().first(); list,
const scalar maxLimit = data.last().first(); lookupValue,
bounds::repeatableBounding(bounding_)
if (lookupValue < minLimit) );
{
switch (bounding_)
{
case bounds::normalBounding::ERROR:
{
FatalErrorInFunction
<< "value (" << lookupValue << ") less than lower "
<< "bound (" << minLimit << ")" << nl
<< exit(FatalError);
break;
}
case bounds::normalBounding::WARN:
{
WarningInFunction
<< "value (" << lookupValue << ") less than lower "
<< "bound (" << minLimit << ")" << nl
<< " Continuing with the first entry"
<< endl;
// Behaviour as per CLAMP
return data.first().second();
break;
}
case bounds::normalBounding::CLAMP:
{
return data.first().second();
break;
}
}
}
else if (lookupValue >= maxLimit)
{
switch (bounding_)
{
case bounds::normalBounding::ERROR:
{
FatalErrorInFunction
<< "value (" << lookupValue << ") greater than upper "
<< "bound (" << maxLimit << ")" << nl
<< exit(FatalError);
break;
}
case bounds::normalBounding::WARN:
{
WarningInFunction
<< "value (" << lookupValue << ") greater than upper "
<< "bound (" << maxLimit << ")" << nl
<< " Continuing with the last entry"
<< endl;
// Behaviour as per CLAMP
return data.last().second();
break;
}
case bounds::normalBounding::CLAMP:
{
return data.last().second();
break;
}
}
}
// look for the correct range in X
label lo = 0;
label hi = 0;
for (label i = 0; i < n; ++i)
{
if (lookupValue >= data[i].first())
{
lo = hi = i;
}
else
{
hi = i;
break;
}
}
if (lo == hi)
{
return data[lo].second();
}
else
{
Type m =
(data[hi].second() - data[lo].second())
/(data[hi].first() - data[lo].first());
// normal interpolation
return data[lo].second() + m*(lookupValue - data[lo].first());
}
} }
@ -244,7 +151,7 @@ Foam::label Foam::interpolation2DTable<Type>::Xi
const bool reverse const bool reverse
) const ) const
{ {
const table& t = *this; const List<value_type>& t = *this;
label limitI = 0; label limitI = 0;
if (reverse) if (reverse)
@ -259,15 +166,14 @@ Foam::label Foam::interpolation2DTable<Type>::Xi
case bounds::normalBounding::ERROR: case bounds::normalBounding::ERROR:
{ {
FatalErrorInFunction FatalErrorInFunction
<< "value (" << valueX << ") out of bounds" << "value (" << valueX << ") out of bounds" << nl
<< exit(FatalError); << exit(FatalError);
break; break;
} }
case bounds::normalBounding::WARN: case bounds::normalBounding::WARN:
{ {
WarningInFunction WarningInFunction
<< "value (" << valueX << ") out of bounds" << "value (" << valueX << ") out of bounds" << nl;
<< endl;
// Behaviour as per CLAMP // Behaviour as per CLAMP
return limitI; return limitI;
@ -290,11 +196,11 @@ Foam::label Foam::interpolation2DTable<Type>::Xi
label i = 0; label i = 0;
if (reverse) if (reverse)
{ {
label nX = t.size(); const label nX = t.size();
i = 0; i = 0;
while ((i < nX) && (valueX > t[i].first())) while ((i < nX) && (valueX > t[i].first()))
{ {
i++; ++i;
} }
} }
else else
@ -302,7 +208,7 @@ Foam::label Foam::interpolation2DTable<Type>::Xi
i = t.size() - 1; i = t.size() - 1;
while ((i > 0) && (valueX < t[i].first())) while ((i > 0) && (valueX < t[i].first()))
{ {
i--; --i;
} }
} }
@ -319,66 +225,61 @@ Type Foam::interpolation2DTable<Type>::operator()
const scalar valueY const scalar valueY
) const ) const
{ {
// Considers all of the list in Y being equal const List<value_type>& t = *this;
const label nX = this->size();
const table& t = *this; // Assumes all of the list in Y being equal length
const label nX = t.size();
if (nX == 0) if (nX == 0)
{ {
WarningInFunction WarningInFunction
<< "cannot interpolate a zero-sized table - returning zero" << endl; << "Cannot interpolate zero-sized table - returning zero" << nl;
return Zero; return Zero;
} }
else if (nX == 1) else if (nX == 1)
{ {
// only 1 column (in X) - interpolate to find Y value // Only 1 column (in X) - simply interpolate to find Y value
return interpolateValue(t.first().second(), valueY); return interpolateValue(t.first().second(), valueY);
} }
else
// Find low and high indices in the X range that bound valueX
const label lo = Xi(lessOp<scalar>(), valueX, false);
const label hi = Xi(greaterOp<scalar>(), valueX, true);
if (lo == hi)
{ {
// have 2-D data, interpolate return interpolateValue(t[lo].second(), valueY);
// find low and high indices in the X range that bound valueX
const label x0i = Xi(lessOp<scalar>(), valueX, false);
const label x1i = Xi(greaterOp<scalar>(), valueX, true);
if (x0i == x1i)
{
return interpolateValue(t[x0i].second(), valueY);
}
else
{
Type y0(interpolateValue(t[x0i].second(), valueY));
Type y1(interpolateValue(t[x1i].second(), valueY));
// gradient in X
const scalar x0 = t[x0i].first();
const scalar x1 = t[x1i].first();
Type mX = (y1 - y0)/(x1 - x0);
// interpolate
return y0 + mX*(valueX - x0);
}
} }
// Normal interpolation
const Type y0(interpolateValue(t[lo].second(), valueY));
const Type y1(interpolateValue(t[hi].second(), valueY));
const scalar& x0 = t[lo].first();
const scalar& x1 = t[hi].first();
return (y0 + (y1 - y0)*(valueX - x0)/(x1 - x0));
} }
template<class Type> template<class Type>
void Foam::interpolation2DTable<Type>::checkOrder() const void Foam::interpolation2DTable<Type>::check() const
{ {
const label n = this->size(); const List<value_type>& list = *this;
const table& t = *this;
scalar prevValue = t[0].first(); scalar prevValue(0);
for (label i=1; i<n; ++i) label i = 0;
for (const auto& item : list)
{ {
const scalar currValue = t[i].first(); const scalar& currValue = item.first();
// avoid duplicate values (divide-by-zero error) // Avoid duplicate values (divide-by-zero error)
if (currValue <= prevValue) if (i && currValue <= prevValue)
{ {
FatalErrorInFunction FatalErrorInFunction
<< "out-of-order value: " << "out-of-order value: "
@ -386,6 +287,7 @@ void Foam::interpolation2DTable<Type>::checkOrder() const
<< exit(FatalError); << exit(FatalError);
} }
prevValue = currValue; prevValue = currValue;
++i;
} }
} }

View File

@ -6,6 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2019 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -27,8 +28,8 @@ Class
Foam::interpolation2DTable Foam::interpolation2DTable
Description Description
2D table interpolation. The data must be in ascending order in both 2D table interpolation.
dimensions x and y. The data must be in ascending order in both dimensions x and y.
SourceFiles SourceFiles
interpolation2DTable.C interpolation2DTable.C
@ -38,10 +39,7 @@ SourceFiles
#ifndef interpolation2DTable_H #ifndef interpolation2DTable_H
#define interpolation2DTable_H #define interpolation2DTable_H
#include "List.H" #include "interpolationTable.H"
#include "Tuple2.H"
#include "tableBounds.H"
#include "tableReader.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -57,17 +55,7 @@ class interpolation2DTable
: :
public List<Tuple2<scalar, List<Tuple2<scalar, Type>>>> public List<Tuple2<scalar, List<Tuple2<scalar, Type>>>>
{ {
public: // Private Data
// Public data types
//- Convenience typedef
typedef List<Tuple2<scalar, List<Tuple2<scalar, Type>>>> table;
private:
// Private data
//- Handling for out-of-bound values //- Handling for out-of-bound values
bounds::normalBounding bounding_; bounds::normalBounding bounding_;
@ -84,11 +72,11 @@ private:
//- Read the table of data from file //- Read the table of data from file
void readTable(); void readTable();
//- Return interpolated value in List //- Interpolated value within 1-D list
Type interpolateValue Type interpolateValue
( (
const List<Tuple2<scalar, Type>>& data, const List<Tuple2<scalar, Type>>& list,
const scalar scalar lookupValue
) const; ) const;
//- Return an X index from the matrix //- Return an X index from the matrix
@ -103,6 +91,15 @@ private:
public: public:
// Public Data Types
//- The element data type
typedef Tuple2<scalar, List<Tuple2<scalar, Type>>> value_type;
//- Convenience typedef
typedef List<Tuple2<scalar, List<Tuple2<scalar, Type>>>> table;
// Constructors // Constructors
//- Construct null //- Construct null
@ -117,12 +114,12 @@ public:
); );
//- Construct given the name of the file containing the table of data //- Construct given the name of the file containing the table of data
interpolation2DTable(const fileName& fName); explicit interpolation2DTable(const fileName& fName);
//- Construct by reading file name and outOfBounds from dictionary //- Construct by reading file name and outOfBounds from dictionary
interpolation2DTable(const dictionary& dict); explicit interpolation2DTable(const dictionary& dict);
//- Construct copy //- Copy construct
interpolation2DTable(const interpolation2DTable& interpTable); interpolation2DTable(const interpolation2DTable& interpTable);
@ -130,7 +127,7 @@ public:
//- Check that list is monotonically increasing //- Check that list is monotonically increasing
// Exit with a FatalError if there is a problem // Exit with a FatalError if there is a problem
void checkOrder() const; void check() const;
//- Write //- Write
void write(Ostream& os) const; void write(Ostream& os) const;
@ -138,11 +135,15 @@ public:
// Member Operators // Member Operators
//- Return an element of constant List<Tuple2<scalar, Type>>
const List<Tuple2<scalar, Type>>& operator[](const label) const;
//- Return an interpolated value //- Return an interpolated value
Type operator()(const scalar valueX, const scalar valueY) const; Type operator()(const scalar valueX, const scalar valueY) const;
// Housekeeping
//- Deprecated(2019-08) check list is monotonically increasing
// \deprecated(2019-08) - older name for check() method
void checkOrder() const { check(); }
}; };

View File

@ -6,6 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2019 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -59,7 +60,7 @@ void Foam::interpolationTable<Type>::readTable()
template<class Type> template<class Type>
Foam::interpolationTable<Type>::interpolationTable() Foam::interpolationTable<Type>::interpolationTable()
: :
List<Tuple2<scalar, Type>>(), List<value_type>(),
bounding_(bounds::repeatableBounding::WARN), bounding_(bounds::repeatableBounding::WARN),
fileName_("fileNameIsUndefined"), fileName_("fileNameIsUndefined"),
reader_(nullptr) reader_(nullptr)
@ -74,7 +75,7 @@ Foam::interpolationTable<Type>::interpolationTable
const fileName& fName const fileName& fName
) )
: :
List<Tuple2<scalar, Type>>(values), List<value_type>(values),
bounding_(bounding), bounding_(bounding),
fileName_(fName), fileName_(fName),
reader_(nullptr) reader_(nullptr)
@ -84,7 +85,7 @@ Foam::interpolationTable<Type>::interpolationTable
template<class Type> template<class Type>
Foam::interpolationTable<Type>::interpolationTable(const fileName& fName) Foam::interpolationTable<Type>::interpolationTable(const fileName& fName)
: :
List<Tuple2<scalar, Type>>(), List<value_type>(),
bounding_(bounds::repeatableBounding::WARN), bounding_(bounds::repeatableBounding::WARN),
fileName_(fName), fileName_(fName),
reader_(new openFoamTableReader<Type>(dictionary())) reader_(new openFoamTableReader<Type>(dictionary()))
@ -96,7 +97,7 @@ Foam::interpolationTable<Type>::interpolationTable(const fileName& fName)
template<class Type> template<class Type>
Foam::interpolationTable<Type>::interpolationTable(const dictionary& dict) Foam::interpolationTable<Type>::interpolationTable(const dictionary& dict)
: :
List<Tuple2<scalar, Type>>(), List<value_type>(),
bounding_ bounding_
( (
bounds::repeatableBoundingNames.lookupOrDefault bounds::repeatableBoundingNames.lookupOrDefault
@ -107,7 +108,7 @@ Foam::interpolationTable<Type>::interpolationTable(const dictionary& dict)
true // Failsafe behaviour true // Failsafe behaviour
) )
), ),
fileName_(dict.lookup("file")), fileName_(dict.get<fileName>("file")),
reader_(tableReader<Type>::New(dict)) reader_(tableReader<Type>::New(dict))
{ {
readTable(); readTable();
@ -120,7 +121,7 @@ Foam::interpolationTable<Type>::interpolationTable
const interpolationTable& interpTable const interpolationTable& interpTable
) )
: :
List<Tuple2<scalar, Type>>(interpTable), List<value_type>(interpTable),
bounding_(interpTable.bounding_), bounding_(interpTable.bounding_),
fileName_(interpTable.fileName_), fileName_(interpTable.fileName_),
reader_(interpTable.reader_) // note: steals reader. Used in write(). reader_(interpTable.reader_) // note: steals reader. Used in write().
@ -133,16 +134,17 @@ Foam::interpolationTable<Type>::interpolationTable
template<class Type> template<class Type>
void Foam::interpolationTable<Type>::check() const void Foam::interpolationTable<Type>::check() const
{ {
const label n = this->size(); const List<value_type>& list = *this;
scalar prevValue = this->first().first();
for (label i=1; i<n; ++i) scalar prevValue(0);
label i = 0;
for (const auto& item : list)
{ {
const scalar currValue = const scalar& currValue = item.first();
List<Tuple2<scalar, Type>>::operator[](i).first();
// avoid duplicate values (divide-by-zero error) // Avoid duplicate values (divide-by-zero error)
if (currValue <= prevValue) if (i && currValue <= prevValue)
{ {
FatalErrorInFunction FatalErrorInFunction
<< "out-of-order value: " << "out-of-order value: "
@ -150,6 +152,7 @@ void Foam::interpolationTable<Type>::check() const
<< exit(FatalError); << exit(FatalError);
} }
prevValue = currValue; prevValue = currValue;
++i;
} }
} }
@ -167,19 +170,20 @@ void Foam::interpolationTable<Type>::write(Ostream& os) const
template<class Type> template<class Type>
Type Foam::interpolationTable<Type>::rateOfChange(const scalar value) const Type Foam::interpolationTable<Type>::rateOfChange(scalar lookupValue) const
{ {
label n = this->size(); const List<value_type>& list = *this;
const label n = list.size();
if (n <= 1) if (n <= 1)
{ {
// There are not enough entries to provide a rate of change // Not enough entries for a rate of change
return 0; return Zero;
} }
const scalar minLimit = this->first().first(); const scalar minLimit = list.first().first();
const scalar maxLimit = this->last().first(); const scalar maxLimit = list.last().first();
scalar lookupValue = value;
if (lookupValue < minLimit) if (lookupValue < minLimit)
{ {
@ -188,31 +192,32 @@ Type Foam::interpolationTable<Type>::rateOfChange(const scalar value) const
case bounds::repeatableBounding::ERROR: case bounds::repeatableBounding::ERROR:
{ {
FatalErrorInFunction FatalErrorInFunction
<< "value (" << lookupValue << ") underflow" << nl << "value (" << lookupValue << ") less than lower "
<< "bound (" << minLimit << ")\n"
<< exit(FatalError); << exit(FatalError);
break; break;
} }
case bounds::repeatableBounding::WARN: case bounds::repeatableBounding::WARN:
{ {
WarningInFunction WarningInFunction
<< "value (" << lookupValue << ") underflow" << nl << "value (" << lookupValue << ") less than lower "
<< " Zero rate of change." << "bound (" << minLimit << ")\n"
<< endl; << " Zero rate of change." << endl;
// Behaviour as per CLAMP // Behaviour as per CLAMP
return 0; return Zero;
break; break;
} }
case bounds::repeatableBounding::CLAMP: case bounds::repeatableBounding::CLAMP:
{ {
return 0; return Zero;
break; break;
} }
case bounds::repeatableBounding::REPEAT: case bounds::repeatableBounding::REPEAT:
{ {
// Adjust lookupValue to >= minLimit // Adjust lookupValue to >= minLimit
scalar span = maxLimit-minLimit; scalar span = maxLimit-minLimit;
lookupValue = fmod(lookupValue-minLimit, span) + minLimit; lookupValue = fmod(lookupValue - minLimit, span) + minLimit;
break; break;
} }
} }
@ -224,31 +229,32 @@ Type Foam::interpolationTable<Type>::rateOfChange(const scalar value) const
case bounds::repeatableBounding::ERROR: case bounds::repeatableBounding::ERROR:
{ {
FatalErrorInFunction FatalErrorInFunction
<< "value (" << lookupValue << ") overflow" << nl << "value (" << lookupValue << ") greater than upper "
<< "bound (" << maxLimit << ")\n"
<< exit(FatalError); << exit(FatalError);
break; break;
} }
case bounds::repeatableBounding::WARN: case bounds::repeatableBounding::WARN:
{ {
WarningInFunction WarningInFunction
<< "value (" << lookupValue << ") overflow" << nl << "value (" << lookupValue << ") greater than upper "
<< " Zero rate of change." << "bound (" << maxLimit << ")\n"
<< endl; << " Zero rate of change." << endl;
// Behaviour as per CLAMP // Behaviour as per CLAMP
return 0; return Zero;
break; break;
} }
case bounds::repeatableBounding::CLAMP: case bounds::repeatableBounding::CLAMP:
{ {
return 0; return Zero;
break; break;
} }
case bounds::repeatableBounding::REPEAT: case bounds::repeatableBounding::REPEAT:
{ {
// Adjust lookupValue <= maxLimit // Adjust lookupValue <= maxLimit
scalar span = maxLimit-minLimit; scalar span = maxLimit-minLimit;
lookupValue = fmod(lookupValue-minLimit, span) + minLimit; lookupValue = fmod(lookupValue - minLimit, span) + minLimit;
break; break;
} }
} }
@ -257,10 +263,10 @@ Type Foam::interpolationTable<Type>::rateOfChange(const scalar value) const
label lo = 0; label lo = 0;
label hi = 0; label hi = 0;
// look for the correct range // Look for the correct range
for (label i = 0; i < n; ++i) for (label i = 0; i < n; ++i)
{ {
if (lookupValue >= List<Tuple2<scalar, Type>>::operator[](i).first()) if (lookupValue >= list[i].first())
{ {
lo = hi = i; lo = hi = i;
} }
@ -273,12 +279,11 @@ Type Foam::interpolationTable<Type>::rateOfChange(const scalar value) const
if (lo == hi) if (lo == hi)
{ {
// we are at the end of the table - or there is only a single entry return Zero;
return 0;
} }
else if (hi == 0) else if (hi == 0)
{ {
// this treatment should only occur under these conditions: // This treatment should only occur under these conditions:
// -> the 'REPEAT' treatment // -> the 'REPEAT' treatment
// -> (0 <= value <= minLimit) // -> (0 <= value <= minLimit)
// -> minLimit > 0 // -> minLimit > 0
@ -287,32 +292,200 @@ Type Foam::interpolationTable<Type>::rateOfChange(const scalar value) const
return return
( (
( (list[hi].second() - list[lo].second())
List<Tuple2<scalar, Type>>::operator[](hi).second() / (list[hi].first() + minLimit - list[lo].first())
- 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[hi].second() - list[lo].second())
/ (list[hi].first() - list[lo].first())
);
}
template<class Type>
Type Foam::interpolationTable<Type>::interpolateValue
(
const List<Tuple2<scalar, Type>>& list,
scalar lookupValue,
bounds::repeatableBounding bounding
)
{
const label n = list.size();
if (n <= 1)
{ {
// normal rate of change #ifdef FULLDEBUG
if (!n)
{
FatalErrorInFunction
<< "Cannot interpolate from zero-sized table" << nl
<< exit(FatalError);
}
#endif
return list.first().second();
}
const scalar minLimit = list.first().first();
const scalar maxLimit = list.last().first();
if (lookupValue < minLimit)
{
switch (bounding)
{
case bounds::repeatableBounding::ERROR:
{
FatalErrorInFunction
<< "value (" << lookupValue << ") less than lower "
<< "bound (" << minLimit << ")\n"
<< exit(FatalError);
break;
}
case bounds::repeatableBounding::WARN:
{
WarningInFunction
<< "value (" << lookupValue << ") less than lower "
<< "bound (" << minLimit << ")\n"
<< " Continuing with the first entry" << endl;
// Behaviour as per CLAMP
return list.first().second();
break;
}
case bounds::repeatableBounding::CLAMP:
{
return list.first().second();
break;
}
case bounds::repeatableBounding::REPEAT:
{
// adjust lookupValue to >= minLimit
const scalar span = maxLimit-minLimit;
lookupValue = fmod(lookupValue - minLimit, span) + minLimit;
break;
}
}
}
else if (lookupValue >= maxLimit)
{
switch (bounding)
{
case bounds::repeatableBounding::ERROR:
{
FatalErrorInFunction
<< "value (" << lookupValue << ") greater than upper "
<< "bound (" << maxLimit << ")\n"
<< exit(FatalError);
break;
}
case bounds::repeatableBounding::WARN:
{
WarningInFunction
<< "value (" << lookupValue << ") greater than upper "
<< "bound (" << maxLimit << ")\n"
<< " Continuing with the last entry" << endl;
// Behaviour as per 'CLAMP'
return list.last().second();
break;
}
case bounds::repeatableBounding::CLAMP:
{
return list.last().second();
break;
}
case bounds::repeatableBounding::REPEAT:
{
// Adjust lookupValue <= maxLimit
const scalar span = maxLimit-minLimit;
lookupValue = fmod(lookupValue - minLimit, span) + minLimit;
break;
}
}
}
label lo = 0;
label hi = 0;
// Look for the correct range
for (label i = 0; i < n; ++i)
{
if (lookupValue >= list[i].first())
{
lo = hi = i;
}
else
{
hi = i;
break;
}
}
if (lo == hi)
{
return list[hi].second();
}
else if (hi == 0)
{
// This treatment 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 return
( (
( list[lo].second()
List<Tuple2<scalar, Type>>::operator[](hi).second() + (list[hi].second() - list[lo].second())
- List<Tuple2<scalar, Type>>::operator[](lo).second() * (lookupValue / minLimit)
)
/(
List<Tuple2<scalar, Type>>::operator[](hi).first()
- List<Tuple2<scalar, Type>>::operator[](lo).first()
)
); );
} }
// Normal interpolation
return
(
list[lo].second()
+ (list[hi].second() - list[lo].second())
* (lookupValue - list[lo].first())
/ (list[hi].first() - list[lo].first())
);
}
template<class Type>
Type Foam::interpolationTable<Type>::interpolateValue
(
scalar lookupValue
) const
{
return interpolateValue(*this, lookupValue, bounding_);
}
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::interpolationTable<Type>::interpolateValues
(
const UList<scalar>& vals
) const
{
auto tfld = tmp<Field<Type>>::New(vals.size());
auto& fld = tfld.ref();
forAll(fld, i)
{
fld[i] = interpolateValue(vals[i]);
}
return tfld;
} }
@ -320,242 +493,105 @@ Type Foam::interpolationTable<Type>::rateOfChange(const scalar value) const
template<class Type> template<class Type>
const Foam::Tuple2<Foam::scalar, Type>& const Foam::Tuple2<Foam::scalar, Type>&
Foam::interpolationTable<Type>::operator[](const label i) const Foam::interpolationTable<Type>::operator[](label idx) const
{ {
label ii = i; const List<value_type>& list = *this;
label n = this->size(); const label n = list.size();
if (n <= 1) if (n <= 1)
{ {
ii = 0; idx = 0;
#ifdef FULLDEBUG
if (!n)
{
FatalErrorInFunction
<< "Cannot interpolate from zero-sized table" << nl
<< exit(FatalError);
}
#endif
} }
else if (ii < 0) else if (idx < 0)
{ {
switch (bounding_) switch (bounding_)
{ {
case bounds::repeatableBounding::ERROR: case bounds::repeatableBounding::ERROR:
{ {
FatalErrorInFunction FatalErrorInFunction
<< "index (" << ii << ") underflow" << nl << "index (" << idx << ") underflow" << nl
<< exit(FatalError); << exit(FatalError);
break; break;
} }
case bounds::repeatableBounding::WARN: case bounds::repeatableBounding::WARN:
{ {
WarningInFunction WarningInFunction
<< "index (" << ii << ") underflow" << nl << "index (" << idx << ") underflow" << nl
<< " Continuing with the first entry" << " Continuing with the first entry" << nl;
<< endl;
// Behaviour as per 'CLAMP' // Behaviour as per 'CLAMP'
ii = 0; idx = 0;
break; break;
} }
case bounds::repeatableBounding::CLAMP: case bounds::repeatableBounding::CLAMP:
{ {
ii = 0; idx = 0;
break; break;
} }
case bounds::repeatableBounding::REPEAT: case bounds::repeatableBounding::REPEAT:
{ {
while (ii < 0) while (idx < 0)
{ {
ii += n; idx += n;
} }
break; break;
} }
} }
} }
else if (ii >= n) else if (idx >= n)
{ {
switch (bounding_) switch (bounding_)
{ {
case bounds::repeatableBounding::ERROR: case bounds::repeatableBounding::ERROR:
{ {
FatalErrorInFunction FatalErrorInFunction
<< "index (" << ii << ") overflow" << nl << "index (" << idx << ") overflow" << nl
<< exit(FatalError); << exit(FatalError);
break; break;
} }
case bounds::repeatableBounding::WARN: case bounds::repeatableBounding::WARN:
{ {
WarningInFunction WarningInFunction
<< "index (" << ii << ") overflow" << nl << "index (" << idx << ") overflow" << nl
<< " Continuing with the last entry" << " Continuing with the last entry" << nl;
<< endl;
// Behaviour as per 'CLAMP' // Behaviour as per 'CLAMP'
ii = n - 1; idx = n - 1;
break; break;
} }
case bounds::repeatableBounding::CLAMP: case bounds::repeatableBounding::CLAMP:
{ {
ii = n - 1; idx = n - 1;
break; break;
} }
case bounds::repeatableBounding::REPEAT: case bounds::repeatableBounding::REPEAT:
{ {
while (ii >= n) while (idx >= n)
{ {
ii -= n; idx -= n;
} }
break; break;
} }
} }
} }
return List<Tuple2<scalar, Type>>::operator[](ii); return list[idx];
} }
template<class Type> template<class Type>
Type Foam::interpolationTable<Type>::operator()(const scalar value) const Type Foam::interpolationTable<Type>::operator()(scalar lookupValue) const
{ {
label n = this->size(); return interpolateValue(*this, lookupValue, bounding_);
if (n <= 1)
{
return this->first().second();
}
const scalar minLimit = this->first().first();
const scalar maxLimit = this->last().first();
scalar lookupValue = value;
if (lookupValue < minLimit)
{
switch (bounding_)
{
case bounds::repeatableBounding::ERROR:
{
FatalErrorInFunction
<< "value (" << lookupValue << ") underflow" << nl
<< exit(FatalError);
break;
}
case bounds::repeatableBounding::WARN:
{
WarningInFunction
<< "value (" << lookupValue << ") underflow" << nl
<< " Continuing with the first entry"
<< endl;
// Behaviour as per CLAMP
return this->first().second();
break;
}
case bounds::repeatableBounding::CLAMP:
{
return this->first().second();
break;
}
case bounds::repeatableBounding::REPEAT:
{
// adjust lookupValue to >= minLimit
const scalar span = maxLimit-minLimit;
lookupValue = fmod(lookupValue-minLimit, span) + minLimit;
break;
}
}
}
else if (lookupValue >= maxLimit)
{
switch (bounding_)
{
case bounds::repeatableBounding::ERROR:
{
FatalErrorInFunction
<< "value (" << lookupValue << ") overflow" << nl
<< exit(FatalError);
break;
}
case bounds::repeatableBounding::WARN:
{
WarningInFunction
<< "value (" << lookupValue << ") overflow" << nl
<< " Continuing with the last entry"
<< endl;
// Behaviour as per 'CLAMP'
return this->last().second();
break;
}
case bounds::repeatableBounding::CLAMP:
{
return this->last().second();
break;
}
case bounds::repeatableBounding::REPEAT:
{
// adjust lookupValue <= maxLimit
const scalar span = maxLimit-minLimit;
lookupValue = fmod(lookupValue-minLimit, span) + minLimit;
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 List<Tuple2<scalar, Type>>::operator[](hi).second();
}
else if (hi == 0)
{
// this treatment 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[](lo).second()
+ (
List<Tuple2<scalar, Type>>::operator[](hi).second()
- List<Tuple2<scalar, Type>>::operator[](lo).second()
)
*(lookupValue / minLimit)
);
}
else
{
// normal interpolation
return
(
List<Tuple2<scalar, Type>>::operator[](lo).second()
+ (
List<Tuple2<scalar, Type>>::operator[](hi).second()
- List<Tuple2<scalar, Type>>::operator[](lo).second()
)
*(
lookupValue
- List<Tuple2<scalar, Type>>::operator[](lo).first()
)
/(
List<Tuple2<scalar, Type>>::operator[](hi).first()
- List<Tuple2<scalar, Type>>::operator[](lo).first()
)
);
}
} }

View File

@ -6,6 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2019 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -36,7 +37,6 @@ Description
If \c repeat is chosen for the out-of-bounds handling, the final time If \c repeat is chosen for the out-of-bounds handling, the final time
value is treated as being equivalent to time=0 for the following periods. value is treated as being equivalent to time=0 for the following periods.
The construct from dictionary reads a filename from a dictionary and The construct from dictionary reads a filename from a dictionary and
has an optional readerType. Default is to read OpenFOAM format. The only has an optional readerType. Default is to read OpenFOAM format. The only
other format is csv (comma separated values): other format is csv (comma separated values):
@ -65,10 +65,10 @@ SourceFiles
#include "List.H" #include "List.H"
#include "Tuple2.H" #include "Tuple2.H"
#include "tableBounds.H" #include "tableBounds.H"
#include "tableReader.H" #include "tableReader.H"
#include "autoPtr.H" #include "autoPtr.H"
#include "Field.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -84,7 +84,7 @@ class interpolationTable
: :
public List<Tuple2<scalar, Type>> public List<Tuple2<scalar, Type>>
{ {
// Private data // Private Data
//- Handling for out-of-bound values //- Handling for out-of-bound values
bounds::repeatableBounding bounding_; bounds::repeatableBounding bounding_;
@ -104,6 +104,15 @@ class interpolationTable
public: public:
// Public Data Types
//- The element data type
typedef Tuple2<scalar, Type> value_type;
//- The mapped data type
typedef Type mapped_type;
// Constructors // Constructors
//- Construct null //- Construct null
@ -118,19 +127,28 @@ public:
); );
//- Construct given the name of the file containing the table of data //- Construct given the name of the file containing the table of data
interpolationTable(const fileName& fName); explicit interpolationTable(const fileName& fName);
//- Construct by reading file name and outOfBounds from dictionary //- Construct by reading file name and outOfBounds from dictionary
// and read the table from that file. //- and read the table from that file.
// This is a specialised constructor used by patchFields // This is a specialised constructor used by patchFields
interpolationTable(const dictionary& dict); explicit interpolationTable(const dictionary& dict);
//- Construct copy //- Copy construct
interpolationTable(const interpolationTable& interpTable); interpolationTable(const interpolationTable& interpTable);
// Member Functions // Member Functions
//- Return an interpolated value in List
static Type interpolateValue
(
const List<Tuple2<scalar, Type>>& list,
scalar lookupValue,
bounds::repeatableBounding = bounds::repeatableBounding::CLAMP
);
//- Check that list is monotonically increasing //- Check that list is monotonically increasing
// Exit with a FatalError if there is a problem // Exit with a FatalError if there is a problem
void check() const; void check() const;
@ -139,17 +157,26 @@ public:
void write(Ostream& os) const; void write(Ostream& os) const;
//- Return the rate of change at the interpolation location //- Return the rate of change at the interpolation location
// for the give value //- for the given lookup value
Type rateOfChange(const scalar) const; Type rateOfChange(scalar lookupValue) const;
//- Return an interpolated value
Type interpolateValue(scalar lookupValue) const;
//- Return multiple interpolated values
tmp<Field<Type>> interpolateValues
(
const UList<scalar>& vals
) const;
// Member Operators // Member Operators
//- Return an element of constant Tuple2<scalar, Type> //- Return an element of constant Tuple2<scalar, Type>
const Tuple2<scalar, Type>& operator[](const label) const; const Tuple2<scalar, Type>& operator[](label idx) const;
//- Return an interpolated value //- Return an interpolated value
Type operator()(const scalar) const; Type operator()(scalar lookupValue) const;
}; };

View File

@ -6,6 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2019 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -38,7 +39,7 @@ Foam::Function1Types::Table<Type>::Table
: :
TableBase<Type>(entryName, dict) TableBase<Type>(entryName, dict)
{ {
Istream& is(dict.lookup(entryName)); Istream& is = dict.lookup(entryName);
word entryType(is); word entryType(is);
is >> this->table_; is >> this->table_;
TableBase<Type>::check(); TableBase<Type>::check();
@ -52,11 +53,4 @@ Foam::Function1Types::Table<Type>::Table(const Table<Type>& tbl)
{} {}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
template<class Type>
Foam::Function1Types::Table<Type>::~Table()
{}
// ************************************************************************* // // ************************************************************************* //

View File

@ -6,6 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2019 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -72,7 +73,6 @@ class Table
//- No copy assignment //- No copy assignment
void operator=(const Table<Type>&) = delete; void operator=(const Table<Type>&) = delete;
public: public:
//- Runtime type information //- Runtime type information
@ -81,7 +81,7 @@ public:
// Constructors // Constructors
//- Construct from entry name and Istream //- Construct from entry name and dictionary
Table(const word& entryName, const dictionary& dict); Table(const word& entryName, const dictionary& dict);
//- Copy constructor //- Copy constructor
@ -95,7 +95,7 @@ public:
//- Destructor //- Destructor
virtual ~Table(); virtual ~Table() = default;
}; };

View File

@ -6,6 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2019 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -39,15 +40,15 @@ Foam::Function1Types::TableBase<Type>::interpolator() const
{ {
// Re-work table into linear list // Re-work table into linear list
tableSamplesPtr_.reset(new scalarField(table_.size())); tableSamplesPtr_.reset(new scalarField(table_.size()));
scalarField& tableSamples = tableSamplesPtr_(); scalarField& samples = *tableSamplesPtr_;
forAll(table_, i) forAll(table_, i)
{ {
tableSamples[i] = table_[i].first(); samples[i] = table_[i].first();
} }
interpolatorPtr_ = interpolationWeights::New interpolatorPtr_ = interpolationWeights::New
( (
interpolationScheme_, interpolationScheme_,
tableSamples samples
); );
} }
@ -116,21 +117,23 @@ void Foam::Function1Types::TableBase<Type>::check() const
<< nl << exit(FatalError); << nl << exit(FatalError);
} }
const label n = table_.size(); scalar prevValue(0);
scalar prevValue = table_[0].first();
for (label i = 1; i < n; ++i) label i = 0;
for (const auto& item : table_)
{ {
const scalar currValue = table_[i].first(); const scalar& currValue = item.first();
// avoid duplicate values (divide-by-zero error) // Avoid duplicate values (divide-by-zero error)
if (currValue <= prevValue) if (i && currValue <= prevValue)
{ {
FatalErrorInFunction FatalErrorInFunction
<< "out-of-order value: " << currValue << " at index " << i << "out-of-order value: "
<< currValue << " at index " << i << nl
<< exit(FatalError); << exit(FatalError);
} }
prevValue = currValue; prevValue = currValue;
++i;
} }
} }
@ -142,45 +145,44 @@ bool Foam::Function1Types::TableBase<Type>::checkMinBounds
scalar& xDash scalar& xDash
) const ) const
{ {
if (x < table_.first().first()) const scalar minLimit = table_.first().first();
const scalar maxLimit = table_.last().first();
if (x < minLimit)
{ {
switch (bounding_) switch (bounding_)
{ {
case bounds::repeatableBounding::ERROR: case bounds::repeatableBounding::ERROR:
{ {
FatalErrorInFunction FatalErrorInFunction
<< "value (" << x << ") underflow" << "value (" << x << ") less than lower "
<< "bound (" << minLimit << ")" << nl
<< exit(FatalError); << exit(FatalError);
break; break;
} }
case bounds::repeatableBounding::WARN: case bounds::repeatableBounding::WARN:
{ {
WarningInFunction WarningInFunction
<< "value (" << x << ") underflow" << nl << "value (" << x << ") less than lower "
<< endl; << "bound (" << minLimit << ")" << nl
<< " Continuing with the first entry" << endl;
// Behaviour as per CLAMP // Behaviour as per CLAMP
xDash = table_.first().first(); xDash = minLimit;
return true; return true;
break; break;
} }
case bounds::repeatableBounding::CLAMP: case bounds::repeatableBounding::CLAMP:
{ {
xDash = table_.first().first(); xDash = minLimit;
return true; return true;
break; break;
} }
case bounds::repeatableBounding::REPEAT: case bounds::repeatableBounding::REPEAT:
{ {
// adjust x to >= minX // Adjust x to >= minX
const scalar span = const scalar span = maxLimit - minLimit;
table_.last().first() - table_.first().first(); xDash = fmod(x - minLimit, span) + minLimit;
xDash =
(
fmod(x - table_.first().first(), span)
+ table_.first().first()
);
break; break;
} }
} }
@ -201,45 +203,44 @@ bool Foam::Function1Types::TableBase<Type>::checkMaxBounds
scalar& xDash scalar& xDash
) const ) const
{ {
if (x > table_.last().first()) const scalar minLimit = table_.first().first();
const scalar maxLimit = table_.last().first();
if (x > maxLimit)
{ {
switch (bounding_) switch (bounding_)
{ {
case bounds::repeatableBounding::ERROR: case bounds::repeatableBounding::ERROR:
{ {
FatalErrorInFunction FatalErrorInFunction
<< "value (" << x << ") overflow" << "value (" << x << ") greater than upper "
<< "bound (" << maxLimit << ")" << nl
<< exit(FatalError); << exit(FatalError);
break; break;
} }
case bounds::repeatableBounding::WARN: case bounds::repeatableBounding::WARN:
{ {
WarningInFunction WarningInFunction
<< "value (" << x << ") overflow" << nl << "value (" << x << ") greater than upper "
<< endl; << "bound (" << maxLimit << ")" << nl
<< " Continuing with the last entry" << endl;
// Behaviour as per CLAMP // Behaviour as per CLAMP
xDash = table_.last().first(); xDash = maxLimit;
return true; return true;
break; break;
} }
case bounds::repeatableBounding::CLAMP: case bounds::repeatableBounding::CLAMP:
{ {
xDash = table_.last().first(); xDash = maxLimit;
return true; return true;
break; break;
} }
case bounds::repeatableBounding::REPEAT: case bounds::repeatableBounding::REPEAT:
{ {
// adjust x to >= minX // Adjust x to >= minX
const scalar span = const scalar span = maxLimit - minLimit;
table_.last().first() - table_.first().first(); xDash = fmod(x - minLimit, span) + minLimit;
xDash =
(
fmod(x - table_.first().first(), span)
+ table_.first().first()
);
break; break;
} }
} }
@ -256,10 +257,9 @@ bool Foam::Function1Types::TableBase<Type>::checkMaxBounds
template<class Type> template<class Type>
void Foam::Function1Types::TableBase<Type>::convertTimeBase(const Time& t) void Foam::Function1Types::TableBase<Type>::convertTimeBase(const Time& t)
{ {
forAll(table_, i) for (auto& item : table_)
{ {
scalar value = table_[i].first(); item.first() = t.userTimeToTime(item.first());
table_[i].first() = t.userTimeToTime(value);
} }
tableSamplesPtr_.clear(); tableSamplesPtr_.clear();
@ -318,8 +318,8 @@ Type Foam::Function1Types::TableBase<Type>::integrate
template<class Type> template<class Type>
Foam::tmp<Foam::scalarField> Foam::Function1Types::TableBase<Type>::x() const Foam::tmp<Foam::scalarField> Foam::Function1Types::TableBase<Type>::x() const
{ {
tmp<scalarField> tfld(new scalarField(table_.size(), Zero)); auto tfld = tmp<scalarField>::New(table_.size(), Zero);
scalarField& fld = tfld.ref(); auto& fld = tfld.ref();
forAll(table_, i) forAll(table_, i)
{ {
@ -333,8 +333,8 @@ Foam::tmp<Foam::scalarField> Foam::Function1Types::TableBase<Type>::x() const
template<class Type> template<class Type>
Foam::tmp<Foam::Field<Type>> Foam::Function1Types::TableBase<Type>::y() const Foam::tmp<Foam::Field<Type>> Foam::Function1Types::TableBase<Type>::y() const
{ {
tmp<Field<Type>> tfld(new Field<Type>(table_.size(), Zero)); auto tfld = tmp<Field<Type>>::New(table_.size(), Zero);
Field<Type>& fld = tfld.ref(); auto& fld = tfld.ref();
forAll(table_, i) forAll(table_, i)
{ {
@ -348,12 +348,14 @@ Foam::tmp<Foam::Field<Type>> Foam::Function1Types::TableBase<Type>::y() const
template<class Type> template<class Type>
void Foam::Function1Types::TableBase<Type>::writeEntries(Ostream& os) const void Foam::Function1Types::TableBase<Type>::writeEntries(Ostream& os) const
{ {
os.writeEntryIfDifferent<word> if (bounds::repeatableBounding::CLAMP != bounding_)
( {
"outOfBounds", os.writeEntry
bounds::repeatableBoundingNames[bounds::repeatableBounding::CLAMP], (
bounds::repeatableBoundingNames[bounding_] "outOfBounds",
); bounds::repeatableBoundingNames[bounding_]
);
}
os.writeEntryIfDifferent<word> os.writeEntryIfDifferent<word>
( (