Commit 51d46079 authored by Mark Olesen's avatar Mark Olesen
Browse files

ENH: consolidate table bounding (issue #520)

- replace duplicate code with global bounds enums and Enum
parent 45dabbfe
......@@ -123,6 +123,7 @@ $(ranges)/labelRange/labelRange.C
$(ranges)/labelRange/labelRanges.C
$(ranges)/scalarRange/scalarRange.C
$(ranges)/scalarRange/scalarRanges.C
$(ranges)/tableBounds/tableBounds.C
spatialVectorAlgebra = primitives/spatialVectorAlgebra
$(spatialVectorAlgebra)/SpatialVector/spatialVector/spatialVector.C
......
......@@ -55,7 +55,7 @@ template<class Type>
Foam::interpolation2DTable<Type>::interpolation2DTable()
:
List<Tuple2<scalar, List<Tuple2<scalar, Type>>>>(),
boundsHandling_(interpolation2DTable::WARN),
bounding_(bounds::normalBounding::WARN),
fileName_("fileNameIsUndefined"),
reader_(nullptr)
{}
......@@ -65,12 +65,12 @@ template<class Type>
Foam::interpolation2DTable<Type>::interpolation2DTable
(
const List<Tuple2<scalar, List<Tuple2<scalar, Type>>>>& values,
const boundsHandling bounds,
const bounds::normalBounding bounding,
const fileName& fName
)
:
List<Tuple2<scalar, List<Tuple2<scalar, Type>>>>(values),
boundsHandling_(bounds),
bounding_(bounding),
fileName_(fName),
reader_(nullptr)
{}
......@@ -80,7 +80,7 @@ template<class Type>
Foam::interpolation2DTable<Type>::interpolation2DTable(const fileName& fName)
:
List<Tuple2<scalar, List<Tuple2<scalar, Type>>>>(),
boundsHandling_(interpolation2DTable::WARN),
bounding_(bounds::normalBounding::WARN),
fileName_(fName),
reader_(new openFoamTableReader<Type>(dictionary()))
{
......@@ -92,7 +92,15 @@ template<class Type>
Foam::interpolation2DTable<Type>::interpolation2DTable(const dictionary& dict)
:
List<Tuple2<scalar, List<Tuple2<scalar, Type>>>>(),
boundsHandling_(wordToBoundsHandling(dict.lookup("outOfBounds"))),
bounding_
(
bounds::normalBoundingNames.lookupOrFailsafe
(
"outOfBounds",
dict,
bounds::normalBounding::WARN
)
),
fileName_(dict.lookup("file")),
reader_(tableReader<Type>::New(dict))
{
......@@ -107,7 +115,7 @@ Foam::interpolation2DTable<Type>::interpolation2DTable
)
:
List<Tuple2<scalar, List<Tuple2<scalar, Type>>>>(interpTable),
boundsHandling_(interpTable.boundsHandling_),
bounding_(interpTable.bounding_),
fileName_(interpTable.fileName_),
reader_(interpTable.reader_) // note: steals reader. Used in write().
{}
......@@ -130,9 +138,9 @@ Type Foam::interpolation2DTable<Type>::interpolateValue
if (lookupValue < minLimit)
{
switch (boundsHandling_)
switch (bounding_)
{
case interpolation2DTable::ERROR:
case bounds::normalBounding::ERROR:
{
FatalErrorInFunction
<< "value (" << lookupValue << ") less than lower "
......@@ -140,18 +148,18 @@ Type Foam::interpolation2DTable<Type>::interpolateValue
<< exit(FatalError);
break;
}
case interpolation2DTable::WARN:
case bounds::normalBounding::WARN:
{
WarningInFunction
<< "value (" << lookupValue << ") less than lower "
<< "bound (" << minLimit << ")" << nl
<< " Continuing with the first entry"
<< endl;
// Behaviour as per 'CLAMP'
// Behaviour as per CLAMP
return data.first().second();
break;
}
case interpolation2DTable::CLAMP:
case bounds::normalBounding::CLAMP:
{
return data.first().second();
break;
......@@ -160,9 +168,9 @@ Type Foam::interpolation2DTable<Type>::interpolateValue
}
else if (lookupValue >= maxLimit)
{
switch (boundsHandling_)
switch (bounding_)
{
case interpolation2DTable::ERROR:
case bounds::normalBounding::ERROR:
{
FatalErrorInFunction
<< "value (" << lookupValue << ") greater than upper "
......@@ -170,18 +178,18 @@ Type Foam::interpolation2DTable<Type>::interpolateValue
<< exit(FatalError);
break;
}
case interpolation2DTable::WARN:
case bounds::normalBounding::WARN:
{
WarningInFunction
<< "value (" << lookupValue << ") greater than upper "
<< "bound (" << maxLimit << ")" << nl
<< " Continuing with the last entry"
<< endl;
// Behaviour as per 'CLAMP'
// Behaviour as per CLAMP
return data.last().second();
break;
}
case interpolation2DTable::CLAMP:
case bounds::normalBounding::CLAMP:
{
return data.last().second();
break;
......@@ -241,25 +249,25 @@ Foam::label Foam::interpolation2DTable<Type>::Xi
if (bop(valueX, t[limitI].first()))
{
switch (boundsHandling_)
switch (bounding_)
{
case interpolation2DTable::ERROR:
case bounds::normalBounding::ERROR:
{
FatalErrorInFunction
<< "value (" << valueX << ") out of bounds"
<< exit(FatalError);
break;
}
case interpolation2DTable::WARN:
case bounds::normalBounding::WARN:
{
WarningInFunction
<< "value (" << valueX << ") out of bounds"
<< endl;
// Behaviour as per 'CLAMP'
// Behaviour as per CLAMP
return limitI;
break;
}
case interpolation2DTable::CLAMP:
case bounds::normalBounding::CLAMP:
{
return limitI;
break;
......@@ -267,7 +275,7 @@ Foam::label Foam::interpolation2DTable<Type>::Xi
default:
{
FatalErrorInFunction
<< "Unhandled enumeration " << boundsHandling_
<< "Unhandled bounding type " << int(bounding_)
<< abort(FatalError);
}
}
......@@ -351,79 +359,6 @@ Type Foam::interpolation2DTable<Type>::operator()
}
template<class Type>
Foam::word Foam::interpolation2DTable<Type>::boundsHandlingToWord
(
const boundsHandling& bound
) const
{
word enumName("warn");
switch (bound)
{
case interpolation2DTable::ERROR:
{
enumName = "error";
break;
}
case interpolation2DTable::WARN:
{
enumName = "warn";
break;
}
case interpolation2DTable::CLAMP:
{
enumName = "clamp";
break;
}
}
return enumName;
}
template<class Type>
typename Foam::interpolation2DTable<Type>::boundsHandling
Foam::interpolation2DTable<Type>::wordToBoundsHandling
(
const word& bound
) const
{
if (bound == "error")
{
return interpolation2DTable::ERROR;
}
else if (bound == "warn")
{
return interpolation2DTable::WARN;
}
else if (bound == "clamp")
{
return interpolation2DTable::CLAMP;
}
else
{
WarningInFunction
<< "bad outOfBounds specifier " << bound << " using 'warn'" << endl;
return interpolation2DTable::WARN;
}
}
template<class Type>
typename Foam::interpolation2DTable<Type>::boundsHandling
Foam::interpolation2DTable<Type>::outOfBounds
(
const boundsHandling& bound
)
{
boundsHandling prev = boundsHandling_;
boundsHandling_ = bound;
return prev;
}
template<class Type>
void Foam::interpolation2DTable<Type>::checkOrder() const
{
......@@ -453,7 +388,7 @@ template<class Type>
void Foam::interpolation2DTable<Type>::write(Ostream& os) const
{
os.writeEntry("file", fileName_);
os.writeEntry("outOfBounds", boundsHandlingToWord(boundsHandling_));
os.writeEntry("outOfBounds", bounds::normalBoundingNames[bounding_]);
os << *this;
}
......
......@@ -38,6 +38,7 @@ SourceFiles
#include "List.H"
#include "Tuple2.H"
#include "tableBounds.H"
#include "tableReader.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
......@@ -58,14 +59,6 @@ public:
// Public data types
//- Enumeration for handling out-of-bound values
enum boundsHandling
{
ERROR, //!< Exit with a FatalError
WARN, //!< Issue warning and clamp value (default)
CLAMP //!< Clamp value to the start/end value
};
//- Convenience typedef
typedef List<Tuple2<scalar, List<Tuple2<scalar, Type>>>> table;
......@@ -74,8 +67,8 @@ private:
// Private data
//- Enumeration for handling out-of-bound values
boundsHandling boundsHandling_;
//- Handling for out-of-bound values
bounds::normalBounding bounding_;
//- File name
fileName fileName_;
......@@ -117,14 +110,14 @@ public:
interpolation2DTable
(
const List<Tuple2<scalar, List<Tuple2<scalar, Type>>>>& values,
const boundsHandling bounds,
const bounds::normalBounding bounding,
const fileName& fName
);
//- Construct given the name of the file containing the table of data
interpolation2DTable(const fileName& fName);
//- Construct by reading the fileName and boundsHandling from dictionary
//- Construct by reading file name and outOfBounds from dictionary
interpolation2DTable(const dictionary& dict);
//- Construct copy
......@@ -133,15 +126,6 @@ public:
// Member Functions
//- Return the out-of-bounds handling as a word
word boundsHandlingToWord(const boundsHandling& bound) const;
//- Return the out-of-bounds handling as an enumeration
boundsHandling wordToBoundsHandling(const word& bound) const;
//- Set the out-of-bounds handling from enum, return previous setting
boundsHandling outOfBounds(const boundsHandling& bound);
//- Check that list is monotonically increasing
// Exit with a FatalError if there is a problem
void checkOrder() const;
......@@ -152,7 +136,7 @@ public:
// Member Operators
//- Return an element of constant Tuple2<scalar, Type>
//- Return an element of constant List<Tuple2<scalar, Type>>
const List<Tuple2<scalar, Type>>& operator[](const label) const;
//- Return an interpolated value
......
......@@ -59,7 +59,7 @@ template<class Type>
Foam::interpolationTable<Type>::interpolationTable()
:
List<Tuple2<scalar, Type>>(),
boundsHandling_(interpolationTable::WARN),
bounding_(bounds::repeatableBounding::WARN),
fileName_("fileNameIsUndefined"),
reader_(nullptr)
{}
......@@ -69,12 +69,12 @@ template<class Type>
Foam::interpolationTable<Type>::interpolationTable
(
const List<Tuple2<scalar, Type>>& values,
const boundsHandling bounds,
const bounds::repeatableBounding bounding,
const fileName& fName
)
:
List<Tuple2<scalar, Type>>(values),
boundsHandling_(bounds),
bounding_(bounding),
fileName_(fName),
reader_(nullptr)
{}
......@@ -84,7 +84,7 @@ template<class Type>
Foam::interpolationTable<Type>::interpolationTable(const fileName& fName)
:
List<Tuple2<scalar, Type>>(),
boundsHandling_(interpolationTable::WARN),
bounding_(bounds::repeatableBounding::WARN),
fileName_(fName),
reader_(new openFoamTableReader<Type>(dictionary()))
{
......@@ -96,7 +96,15 @@ template<class Type>
Foam::interpolationTable<Type>::interpolationTable(const dictionary& dict)
:
List<Tuple2<scalar, Type>>(),
boundsHandling_(wordToBoundsHandling(dict.lookup("outOfBounds"))),
bounding_
(
bounds::repeatableBoundingNames.lookupOrFailsafe
(
"outOfBounds",
dict,
bounds::repeatableBounding::WARN
)
),
fileName_(dict.lookup("file")),
reader_(tableReader<Type>::New(dict))
{
......@@ -111,7 +119,7 @@ Foam::interpolationTable<Type>::interpolationTable
)
:
List<Tuple2<scalar, Type>>(interpTable),
boundsHandling_(interpTable.boundsHandling_),
bounding_(interpTable.bounding_),
fileName_(interpTable.fileName_),
reader_(interpTable.reader_) // note: steals reader. Used in write().
{}
......@@ -120,88 +128,6 @@ Foam::interpolationTable<Type>::interpolationTable
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
Foam::word Foam::interpolationTable<Type>::boundsHandlingToWord
(
const boundsHandling& bound
) const
{
word enumName("warn");
switch (bound)
{
case interpolationTable::ERROR:
{
enumName = "error";
break;
}
case interpolationTable::WARN:
{
enumName = "warn";
break;
}
case interpolationTable::CLAMP:
{
enumName = "clamp";
break;
}
case interpolationTable::REPEAT:
{
enumName = "repeat";
break;
}
}
return enumName;
}
template<class Type>
typename Foam::interpolationTable<Type>::boundsHandling
Foam::interpolationTable<Type>::wordToBoundsHandling
(
const word& bound
) const
{
if (bound == "error")
{
return interpolationTable::ERROR;
}
else if (bound == "warn")
{
return interpolationTable::WARN;
}
else if (bound == "clamp")
{
return interpolationTable::CLAMP;
}
else if (bound == "repeat")
{
return interpolationTable::REPEAT;
}
else
{
WarningInFunction
<< "bad outOfBounds specifier " << bound << " using 'warn'" << endl;
return interpolationTable::WARN;
}
}
template<class Type>
typename Foam::interpolationTable<Type>::boundsHandling
Foam::interpolationTable<Type>::outOfBounds
(
const boundsHandling& bound
)
{
boundsHandling prev = boundsHandling_;
boundsHandling_ = bound;
return prev;
}
template<class Type>
void Foam::interpolationTable<Type>::check() const
{
......@@ -230,7 +156,7 @@ template<class Type>
void Foam::interpolationTable<Type>::write(Ostream& os) const
{
os.writeEntry("file", fileName_);
os.writeEntry("outOfBounds", boundsHandlingToWord(boundsHandling_));
os.writeEntry("outOfBounds", bounds::repeatableBoundingNames[bounding_]);
if (reader_.valid())
{
reader_->write(os);
......@@ -255,33 +181,33 @@ Type Foam::interpolationTable<Type>::rateOfChange(const scalar value) const
if (lookupValue < minLimit)
{
switch (boundsHandling_)
switch (bounding_)
{
case interpolationTable::ERROR:
case bounds::repeatableBounding::ERROR:
{
FatalErrorInFunction
<< "value (" << lookupValue << ") underflow" << nl
<< exit(FatalError);
break;
}
case interpolationTable::WARN:
case bounds::repeatableBounding::WARN:
{
WarningInFunction
<< "value (" << lookupValue << ") underflow" << nl
<< " Zero rate of change."
<< endl;
// behaviour as per 'CLAMP'
// Behaviour as per CLAMP
return 0;
break;
}
case interpolationTable::CLAMP:
case bounds::repeatableBounding::CLAMP:
{
return 0;
break;
}
case interpolationTable::REPEAT:
case bounds::repeatableBounding::REPEAT:
{
// adjust lookupValue to >= minLimit
// Adjust lookupValue to >= minLimit
scalar span = maxLimit-minLimit;
lookupValue = fmod(lookupValue-minLimit, span) + minLimit;
break;
......@@ -290,33 +216,33 @@ Type Foam::interpolationTable<Type>::rateOfChange(const scalar value) const
}
else if (lookupValue >= maxLimit)
{
switch (boundsHandling_)
switch (bounding_)
{
case interpolationTable::ERROR:
case bounds::repeatableBounding::ERROR:
{
FatalErrorInFunction
<< "value (" << lookupValue << ") overflow" << nl
<< exit(FatalError);
break;
}
case interpolationTable::WARN:
case bounds::repeatableBounding::WARN:
{
WarningInFunction
<< "value (" << lookupValue << ") overflow" << nl
<< " Zero rate of change."
<< endl;
// Behaviour as per 'CLAMP'
// Behaviour as per CLAMP
return 0;
break;
}
case interpolationTable::CLAMP:
case bounds::repeatableBounding::CLAMP:
{
return 0;
break;
}
case interpolationTable::REPEAT:
case bounds::repeatableBounding::REPEAT:
{
// adjust lookupValue <= maxLimit
// Adjust lookupValue <= maxLimit
scalar span = maxLimit-minLimit;
lookupValue = fmod(lookupValue-minLimit, span) + minLimit;
break;
......@@ -401,16 +327,16 @@ Foam::interpolationTable<Type>::operator[](const label i) const
}
else if (ii < 0)
{
switch (boundsHandling_)
switch (bounding_)
{
case interpolationTable::ERROR:
case bounds::repeatableBounding::ERROR:
{
FatalErrorInFunction
<< "index (" << ii << ") underflow" << nl
<< exit(FatalError);
break;
}
case interpolationTable::WARN:
case bounds::repeatableBounding::WARN:
{
WarningInFunction
<< "index (" << ii << ") underflow" << nl
......@@ -420,12 +346,12 @@ Foam::interpolationTable<Type>::operator[](const label i) const
ii = 0;
break;
}
case interpolationTable::CLAMP:
case bounds::repeatableBounding::CLAMP:
{
ii = 0;
break;
}