mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: interpolationTable improvements
- reduce code duplication, support returning multiple interpolations as a Field
This commit is contained in:
committed by
Andrew Heather
parent
784d3ad5d4
commit
87330972d8
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -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()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -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()
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -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>
|
||||||
(
|
(
|
||||||
|
|||||||
Reference in New Issue
Block a user