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 -------------------------------------------------------------------------------
11 License
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 
33 template<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 
56 template<class Type>
58 :
59  List<value_type>(),
60  bounding_(bounds::normalBounding::WARN),
61  fileName_("fileNameIsUndefined"),
62  reader_(nullptr)
63 {}
64 
65 
66 template<class Type>
68 (
69  const List<Tuple2<scalar, List<Tuple2<scalar, Type>>>>& values,
70  const bounds::normalBounding bounding,
71  const fileName& fName
72 )
73 :
75  bounding_(bounding),
76  fileName_(fName),
77  reader_(nullptr)
78 {}
79 
80 
81 template<class Type>
83 :
84  List<value_type>(),
85  bounding_(bounds::normalBounding::WARN),
86  fileName_(fName),
87  reader_(new openFoamTableReader<Type>())
88 {
89  readTable();
90 }
91 
92 
93 template<class Type>
95 :
96  List<value_type>(),
97  bounding_
98  (
99  bounds::normalBoundingNames.getOrDefault
100  (
101  "outOfBounds",
102  dict,
103  bounds::normalBounding::WARN,
104  true // Failsafe behaviour
105  )
106  ),
107  fileName_(dict.get<fileName>("file")),
108  reader_(tableReader<Type>::New(dict))
109 {
110  readTable();
111 }
112 
113 
114 template<class Type>
116 (
117  const interpolation2DTable& tbl
118 )
119 :
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 
129 template<class Type>
131 (
132  const List<Tuple2<scalar, Type>>& list,
133  scalar lookupValue
134 ) const
135 {
137  (
138  list,
139  lookupValue,
140  bounds::repeatableBounding(bounding_)
141  );
142 }
143 
144 
145 template<class Type>
146 template<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  {
166  case bounds::normalBounding::ERROR:
167  {
169  << "value (" << valueX << ") out of bounds" << nl
170  << exit(FatalError);
171  break;
172  }
173  case bounds::normalBounding::WARN:
174  {
176  << "value (" << valueX << ") out of bounds" << nl;
177 
178  // Behaviour as per CLAMP
179  return limitI;
180  break;
181  }
182  case bounds::normalBounding::CLAMP:
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 
221 template<class Type>
223 (
224  const interpolation2DTable<Type>& rhs
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 
239 template<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 
287 template<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 
313 template<class Type>
315 {
316  os.writeEntry("file", fileName_);
317  os.writeEntry("outOfBounds", bounds::normalBoundingNames[bounding_]);
318 
319  os << *this;
320 }
321 
322 
323 // ************************************************************************* //
Foam::reverse
void reverse(UList< T > &list, const label n)
Definition: UListI.H:449
Foam::openFoamTableReader
Reads an interpolation table from a file - OpenFOAM-format.
Definition: openFoamTableReader.H:52
Foam::fileName
A class for handling file names.
Definition: fileName.H:73
Foam::y1
dimensionedScalar y1(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:282
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
Foam::HashTableOps::values
List< T > values(const HashTable< T, Key, Hash > &tbl, const bool doSort=false)
List of values from HashTable, optionally sorted.
Definition: HashOps.H:149
Foam::interpolation2DTable::interpolation2DTable
interpolation2DTable()
Default construct.
Definition: interpolation2DTable.C:57
Foam::tableReader
Base class to read table data for the interpolationTable.
Definition: tableReader.H:60
Foam::bounds::normalBounding
normalBounding
Enumeration for handling out-of-bound values.
Definition: tableBounds.H:53
Foam::bounds::repeatableBounding
repeatableBounding
Enumeration for handling out-of-bound values that are repeatable.
Definition: tableBounds.H:61
Foam::interpolation2DTable
2D table interpolation. The data must be in ascending order in both dimensions x and y.
Definition: interpolation2DTable.H:53
Foam::check
static void check(const int retVal, const char *what)
Definition: ptscotchDecomp.C:80
Foam::y0
dimensionedScalar y0(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:281
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::FatalError
error FatalError
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:123
Foam::interpolation2DTable::check
void check() const
Check that list is monotonically increasing.
Definition: interpolation2DTable.C:288
os
OBJstream os(runTime.globalPath()/outputName)
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:144
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::lessOp
Definition: ops.H:238
Foam::New
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh >> &tdf1, const word &name, const dimensionSet &dimensions)
Global function forwards to reuseTmpDimensionedField::New.
Definition: DimensionedFieldReuseFunctions.H:105
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::nl
constexpr char nl
Definition: Ostream.H:404
Foam::bounds::normalBoundingNames
const Foam::Enum< normalBounding > normalBoundingNames
Strings corresponding to the normalBounding.
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: BitOps.H:63
Foam::string::expand
string & expand(const bool allowEmpty=false)
Definition: string.C:173
Foam::PtrListOps::get
List< ReturnType > get(const UPtrList< T > &list, const AccessOp &aop)
Foam::interpolationTable
An interpolation/look-up table of scalar vs <Type> values. The reference scalar values must be monoto...
Definition: interpolationTable.H:81
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56
Foam::Tuple2
A 2-tuple for storing two objects of dissimilar types. The container is similar in purpose to std::pa...
Definition: stringOps.H:60
Foam::greaterOp
Definition: ops.H:240
WarningInFunction
#define WarningInFunction
Report a warning using Foam::Warning.
Definition: messageStream.H:328
openFoamTableReader.H
Foam::interpolation2DTable::write
void write(Ostream &os) const
Write.
Definition: interpolation2DTable.C:314