interpolation2DTable.C
Go to the documentation of this file.
1/*---------------------------------------------------------------------------*\
2 ========= |
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4 \\ / O peration |
5 \\ / A nd | www.openfoam.com
6 \\/ M anipulation |
7-------------------------------------------------------------------------------
8 Copyright (C) 2011-2017 OpenFOAM Foundation
9 Copyright (C) 2016-2020 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
12 This file is part of OpenFOAM.
13
14 OpenFOAM is free software: you can redistribute it and/or modify it
15 under the terms of the GNU General Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18
19 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26
27\*---------------------------------------------------------------------------*/
28
29#include "openFoamTableReader.H"
30
31// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
32
33template<class Type>
35{
36 fileName fName(fileName_);
37 fName.expand();
38
39 // Read data from file
40 reader_()(fName, *this);
41
42 if (this->empty())
43 {
45 << "table read from " << fName << " is empty" << nl
46 << exit(FatalError);
47 }
48
49 // Check that the data are in ascending order
50 check();
51}
52
53
54// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
55
56template<class Type>
58:
60 bounding_(bounds::normalBounding::WARN),
61 fileName_("fileNameIsUndefined"),
62 reader_(nullptr)
63{}
64
65
66template<class Type>
68(
69 const List<Tuple2<scalar, List<Tuple2<scalar, Type>>>>& values,
70 const bounds::normalBounding bounding,
71 const fileName& fName
72)
73:
74 List<value_type>(values),
75 bounding_(bounding),
76 fileName_(fName),
77 reader_(nullptr)
78{}
79
80
81template<class Type>
83:
85 bounding_(bounds::normalBounding::WARN),
86 fileName_(fName),
87 reader_(new openFoamTableReader<Type>())
88{
89 readTable();
90}
91
92
93template<class Type>
95:
97 bounding_
98 (
99 bounds::normalBoundingNames.getOrDefault
100 (
101 "outOfBounds",
102 dict,
103 bounds::normalBounding::WARN,
104 true // Failsafe behaviour
106 ),
107 fileName_(dict.get<fileName>("file")),
108 reader_(tableReader<Type>::New(dict))
109{
110 readTable();
111}
112
113
114template<class Type>
117 const interpolation2DTable& tbl
118)
120 List<value_type>(tbl),
121 bounding_(tbl.bounding_),
122 fileName_(tbl.fileName_),
123 reader_(tbl.reader_.clone())
124{}
125
126
127// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
128
129template<class Type>
131(
133 scalar lookupValue
134) const
135{
137 (
138 list,
139 lookupValue,
141 );
142}
143
144
145template<class Type>
146template<class BinaryOp>
148(
149 const BinaryOp& bop,
150 const scalar valueX,
151 const bool reverse
152) const
153{
154 const List<value_type>& t = *this;
155
156 label limitI = 0;
157 if (reverse)
158 {
159 limitI = t.size() - 1;
160 }
161
162 if (bop(valueX, t[limitI].first()))
163 {
164 switch (bounding_)
165 {
167 {
169 << "value (" << valueX << ") out of bounds" << nl
170 << exit(FatalError);
171 break;
172 }
174 {
176 << "value (" << valueX << ") out of bounds" << nl;
177
178 // Behaviour as per CLAMP
179 return limitI;
180 break;
181 }
183 {
184 return limitI;
185 break;
186 }
187 default:
188 {
190 << "Unhandled bounding type " << int(bounding_)
191 << abort(FatalError);
192 }
193 }
194 }
195
196 label i = 0;
197 if (reverse)
198 {
199 const label nX = t.size();
200 i = 0;
201 while ((i < nX) && (valueX > t[i].first()))
202 {
203 ++i;
204 }
205 }
206 else
207 {
208 i = t.size() - 1;
209 while ((i > 0) && (valueX < t[i].first()))
210 {
211 --i;
212 }
213 }
214
215 return i;
216}
217
218
219// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
220
221template<class Type>
223(
225)
226{
227 if (this == &rhs)
228 {
229 return;
230 }
231
232 static_cast<List<value_type>&>(*this) = rhs;
233 bounding_ = rhs.bounding_;
234 fileName_ = rhs.fileName_;
235 reader_.reset(rhs.reader_.clone());
236}
237
238
239template<class Type>
241(
242 const scalar valueX,
243 const scalar valueY
244) const
245{
246 const List<value_type>& t = *this;
247
248 // Assumes all of the list in Y being equal length
249 const label nX = t.size();
250
251 if (nX == 0)
252 {
254 << "Cannot interpolate zero-sized table - returning zero" << nl;
255
256 return Zero;
257 }
258 else if (nX == 1)
259 {
260 // Only 1 column (in X) - simply interpolate to find Y value
261 return interpolateValue(t.first().second(), valueY);
262 }
263
264
265 // Find low and high indices in the X range that bound valueX
266 const label lo = Xi(lessOp<scalar>(), valueX, false);
267 const label hi = Xi(greaterOp<scalar>(), valueX, true);
268
269 if (lo == hi)
270 {
271 return interpolateValue(t[lo].second(), valueY);
272 }
273
274
275 // Normal interpolation
276
277 const Type y0(interpolateValue(t[lo].second(), valueY));
278 const Type y1(interpolateValue(t[hi].second(), valueY));
279
280 const scalar& x0 = t[lo].first();
281 const scalar& x1 = t[hi].first();
282
283 return (y0 + (y1 - y0)*(valueX - x0)/(x1 - x0));
284}
285
286
287template<class Type>
289{
290 const List<value_type>& list = *this;
291
292 scalar prevValue(0);
293
294 label i = 0;
295 for (const auto& item : list)
296 {
297 const scalar& currValue = item.first();
298
299 // Avoid duplicate values (divide-by-zero error)
300 if (i && currValue <= prevValue)
301 {
303 << "out-of-order value: "
304 << currValue << " at index " << i << nl
305 << exit(FatalError);
306 }
307 prevValue = currValue;
308 ++i;
309 }
310}
311
312
313template<class Type>
315{
316 os.writeEntry("file", fileName_);
317 os.writeEntry("outOfBounds", bounds::normalBoundingNames[bounding_]);
318
319 os << *this;
320}
321
322
323// ************************************************************************* //
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: List.H:77
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:62
Ostream & writeEntry(const keyType &key, const T &value)
Write a keyword/value entry.
Definition: Ostream.H:239
T & first()
Return the first element of the list.
Definition: UListI.H:202
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
virtual const volScalarField & Xi() const
Return the flame-wrinkling Xi.
Definition: XiModel.H:212
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:126
friend Ostream & operator(Ostream &, const faMatrix< Type > &)
A class for handling file names.
Definition: fileName.H:76
virtual bool write()
Write the output fields.
2D table interpolation. The data must be in ascending order in both dimensions x and y.
void check() const
Check that list is monotonically increasing.
interpolation2DTable()
Default construct.
static Type interpolateValue(const List< Tuple2< scalar, Type > > &list, scalar lookupValue, bounds::repeatableBounding=bounds::repeatableBounding::CLAMP)
Return an interpolated value in List.
Reads an interpolation table from a file - OpenFOAM-format.
Base class to read table data for the interpolationTable.
Definition: tableReader.H:61
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
OBJstream os(runTime.globalPath()/outputName)
#define WarningInFunction
Report a warning using Foam::Warning.
repeatableBounding
Enumeration for handling out-of-bound values that are repeatable.
Definition: tableBounds.H:62
const Foam::Enum< normalBounding > normalBoundingNames
Strings corresponding to the normalBounding.
normalBounding
Enumeration for handling out-of-bound values.
Definition: tableBounds.H:54
@ WARN
Issue warning and clamp value (this is a good default)
@ ERROR
Exit with a FatalError.
@ CLAMP
Clamp value to the start/end value.
dimensionedScalar y0(const dimensionedScalar &ds)
void reverse(UList< T > &list, const label n)
Reverse the first n elements of the list.
Definition: UListI.H:449
dimensionedScalar y1(const dimensionedScalar &ds)
errorManip< error > abort(error &err)
Definition: errorManip.H:144
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh > > &tdf1, const word &name, const dimensionSet &dimensions)
Global function forwards to reuseTmpDimensionedField::New.
error FatalError
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53
dictionary dict