Table.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "Table.H"
28 
29 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
30 
31 template<class Type>
34 {
35  if (interpolatorPtr_.empty())
36  {
37  // Re-work table into linear list
38  tableSamplesPtr_.reset(new scalarField(values_.size()));
39  scalarField& tableSamples = tableSamplesPtr_();
40  forAll(values_, i)
41  {
42  tableSamples[i] = values_[i].first();
43  }
44  interpolatorPtr_ = interpolationWeights::New
45  (
46  interpolationScheme_,
47  tableSamples
48  );
49  }
50 
51  return interpolatorPtr_();
52 }
53 
54 
55 template<class Type>
57 {
58  if (!values_.size())
59  {
61  << "Table for entry " << this->name() << " is invalid (empty)"
62  << nl << exit(FatalError);
63  }
64 
65  label n = values_.size();
66  scalar prevValue = values_[0].first();
67 
68  for (label i = 1; i < n; ++i)
69  {
70  const scalar currValue = values_[i].first();
71 
72  // avoid duplicate values (divide-by-zero error)
73  if (currValue <= prevValue)
74  {
76  << "out-of-order value: " << currValue << " at index " << i
77  << exit(FatalError);
78  }
79  prevValue = currValue;
80  }
81 }
82 
83 
84 template<class Type>
86 (
87  const scalar x
88 ) const
89 {
90  const bool under = x < values_.first().first();
91  const bool over = x > values_.last().first();
92 
93  auto errorMessage = [&]()
94  {
95  return "value (" + name(x) + ") " + (under ? "under" : "over") + "flow";
96  };
97 
98  if (under || over)
99  {
100  switch (boundsHandling_)
101  {
102  case tableBase::boundsHandling::error:
103  {
105  << errorMessage() << nl << exit(FatalError);
106  break;
107  }
108  case tableBase::boundsHandling::warn:
109  {
111  << errorMessage() << nl << endl;
112  break;
113  }
114  case tableBase::boundsHandling::clamp:
115  {
116  break;
117  }
119  {
120  const scalar t0 = values_.first().first();
121  const scalar t1 = values_.last().first();
122  const scalar dt = t1 - t0;
123  const label n = floor((x - t0)/dt);
124  return x - n*dt;
125  }
126  }
127  }
128 
129  return x;
130 }
131 
132 
133 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
134 
135 template<class Type>
137 (
138  const word& name,
140  const word& interpolationScheme,
141  const autoPtr<TableReader<Type>>& reader,
142  const List<Tuple2<scalar, Type>>& table
143 )
144 :
145  FieldFunction1<Type, Table<Type>>(name),
146  boundsHandling_(boundsHandling),
147  interpolationScheme_(interpolationScheme),
148  values_(table),
149  reader_(reader, false)
150 {}
151 
152 
153 template<class Type>
155 (
156  const word& name,
157  const dictionary& dict
158 )
159 :
160  FieldFunction1<Type, Table<Type>>(name),
161  boundsHandling_
162  (
163  dict.found("outOfBounds")
164  ? tableBase::boundsHandlingNames_.read(dict.lookup("outOfBounds"))
165  : tableBase::boundsHandling::clamp
166  ),
167  interpolationScheme_
168  (
169  dict.lookupOrDefault<word>
170  (
171  "interpolationScheme",
173  )
174  ),
175  values_(),
176  reader_(TableReader<Type>::New(name, dict, this->values_))
177 {
178  check();
179 }
180 
181 
182 template<class Type>
184 :
185  FieldFunction1<Type, Table<Type>>(tbl),
186  boundsHandling_(tbl.boundsHandling_),
187  interpolationScheme_(tbl.interpolationScheme_),
188  values_(tbl.values_),
189  tableSamplesPtr_(tbl.tableSamplesPtr_),
190  interpolatorPtr_(tbl.interpolatorPtr_),
191  reader_(tbl.reader_, false)
192 {}
193 
194 
195 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
196 
197 template<class Type>
199 {}
200 
201 
202 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
203 
204 template<class Type>
206 (
207  const scalar x
208 ) const
209 {
210  const scalar bx = bound(x);
211 
212  Type y = Zero;
213 
214  interpolator().valueWeights(bx, indices_, weights_);
215  forAll(indices_, i)
216  {
217  y += weights_[i]*values_[indices_[i]].second();
218  }
219 
220  return y;
221 }
222 
223 
224 template<class Type>
226 (
227  const scalar x1,
228  const scalar x2
229 ) const
230 {
231  const scalar bx1 = bound(x1);
232  const scalar bx2 = bound(x2);
233 
234  Type sumY = Zero;
235 
236  interpolator().integrationWeights(bx1, bx2, indices_, weights_);
237  forAll(indices_, i)
238  {
239  sumY += weights_[i]*values_[indices_[i]].second();
240  }
241 
242  if (boundsHandling_ == tableBase::boundsHandling::repeat)
243  {
244  const scalar t0 = values_.first().first();
245  const scalar t1 = values_.last().first();
246  const label n = floor(((x2 - x1) - (bx2 - bx1))/(t1 - t0) + 0.5);
247 
248  if (n != 0)
249  {
250  Type sumY01 = Zero;
251 
252  interpolator().integrationWeights(t0, t1, indices_, weights_);
253 
254  forAll(indices_, i)
255  {
256  sumY01 += weights_[i]*values_[indices_[i]].second();
257  }
258 
259  sumY += n*sumY01;
260  }
261  }
262 
263  return sumY;
264 }
265 
266 
267 template<class Type>
270 {
271  tmp<scalarField> tfld(new scalarField(values_.size(), 0.0));
272  scalarField& fld = tfld.ref();
273 
274  forAll(values_, i)
275  {
276  fld[i] = values_[i].first();
277  }
278 
279  return tfld;
280 }
281 
282 
283 template<class Type>
286 {
287  tmp<Field<Type>> tfld(new Field<Type>(values_.size(), Zero));
288  Field<Type>& fld = tfld.ref();
289 
290  forAll(values_, i)
291  {
292  fld[i] = values_[i].second();
293  }
294 
295  return tfld;
296 }
297 
298 
299 template<class Type>
301 {
303  (
304  os,
305  "outOfBounds",
306  tableBase::boundsHandlingNames_[tableBase::boundsHandling::clamp],
307  tableBase::boundsHandlingNames_[boundsHandling_]
308  );
309 
311  (
312  os,
313  "interpolationScheme",
314  linearInterpolationWeights::typeName,
315  interpolationScheme_
316  );
317 
318  reader_->write(os, values_);
319 }
320 
321 
322 // ************************************************************************* //
scalar y
bool found
label n
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
Templated interpolated tabulated data Function1.
Definition: Table.H:122
virtual tmp< scalarField > x() const
Return the reference values.
Definition: Table.C:269
virtual Type integral(const scalar x1, const scalar x2) const
Integrate between two scalars.
Definition: Table.C:226
Table(const word &name, const tableBase::boundsHandling boundsHandling, const word &interpolationScheme, const autoPtr< TableReader< Type >> &reader, const List< Tuple2< scalar, Type >> &table)
Construct from components.
Definition: Table.C:137
virtual void write(Ostream &os) const
Write data to dictionary stream.
Definition: Table.C:300
virtual tmp< Field< Type > > y() const
Return the dependent values.
Definition: Table.C:285
virtual Type value(const scalar x) const
Return Table value as a function of scalar x.
Definition: Table.C:206
virtual ~Table()
Destructor.
Definition: Table.C:198
boundsHandling
Enumeration for handling out-of-bound values.
Definition: tableBase.H:55
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: List.H:91
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:57
Base class to read table data for tables.
Definition: TableReader.H:51
A 2-tuple for storing two objects of different types.
Definition: Tuple2.H:63
T & first()
Return the first element of the list.
Definition: UListI.H:114
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
Definition: autoPtr.H:51
A list of keyword definitions, which are a keyword followed by any number of values (e....
Definition: dictionary.H:160
Abstract base class for interpolating in 1D.
A class for managing temporary objects.
Definition: tmp.H:55
T & ref() const
Return non-const reference or generate a fatal error.
Definition: tmpI.H:181
A class for handling words, derived from string.
Definition: word.H:62
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:306
volScalarField scalarField(fieldObject, mesh)
gmvFile<< "tracers "<< particles.size()<< nl;{ pointField positions(particles.size());label particlei=0;forAllConstIter(Cloud< passiveParticle >, particles, iter) { positions[particlei++]=iter().position(mesh);} for(i=0;i< pTraits< point >::nComponents;i++) { forAll(positions, particlei) { gmvFile<< component(positions[particlei], i)<< ' ';} gmvFile<< nl;}}forAll(lagrangianScalarNames, i){ const word &name=lagrangianScalarNames[i];IOField< scalar > fld(IOobject(name, runTime.name(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
#define WarningInFunction
Report a warning using Foam::Warning.
autoPtr< CompressibleMomentumTransportModel > New(const volScalarField &rho, const volVectorField &U, const surfaceScalarField &phi, const viscosity &viscosity)
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
static const zero Zero
Definition: zero.H:97
bool read(const char *, int32_t &)
Definition: int32IO.C:85
void writeEntryIfDifferent(Ostream &os, const word &entryName, const EntryType &value1, const EntryType &value2)
Helper function to write the keyword and entry only if the.
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
word name(const bool)
Return a word representation of a bool.
Definition: boolIO.C:39
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh >> &tdf1, const word &name, const dimensionSet &dimensions)
bool bound(volScalarField &, const dimensionedScalar &min)
Bound the given scalar field where it is below the specified min value.
Definition: bound.C:31
error FatalError
List< Type > repeat(const UList< Type > &a, const UList< Type > &b)
static const char nl
Definition: Ostream.H:260
dictionary dict