FreeFOAM The Cross-Platform CFD Toolkit
interpolationLookUpTable.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 | Copyright (C) 2008-2010 OpenCFD Ltd.
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 <OpenFOAM/IFstream.H>
27 
28 // * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
29 
30 template <class Type>
32 (
33  const List<scalar>& indices,
34  const bool lastDim
35 ) const
36 {
37  label totalIndex = 0;
38 
39  forAll(dim_, i)
40  {
41  label dim = 1;
42  for (int j = i + 1; j < dim_.size(); j++)
43  {
44  dim *= dim_[j] + 1;
45  }
46 
47  totalIndex +=
48  dim
49  *min
50  (
51  max(label((indices[i] - min_[i])/delta_[i]), 0),
52  dim_[i]
53  );
54  }
55 
56  if (lastDim)
57  {
58  label iLastdim = dim_.size() - 1;
59  totalIndex += Foam::min
60  (
61  max
62  (
63  label((indices[iLastdim] - min_[iLastdim])/delta_[iLastdim]),
64  0
65  ),
66  dim_[iLastdim]
67  );
68  }
69 
70  return totalIndex;
71 }
72 
73 
74 template <class Type>
76 (
77  const scalar indice
78 ) const
79 {
80  label i = 0;
81  label totalIndex =
82  Foam::min
83  (
84  Foam::max
85  (
86  label((indice - min_[i])/delta_[i]),
87  0
88  ),
89  dim_[i]
90  );
91 
92  return totalIndex;
93 }
94 
95 
96 template<class Type>
98 (
99  const scalar lookUpValue,
100  const label interfield
101 ) const
102 {
103  if (lookUpValue >= min_[interfield] && lookUpValue <= max_[interfield])
104  {
105  return true;
106  }
107  else
108  {
109  return false;
110  }
111 }
112 
113 
114 template<class Type>
116 (
117  const label lo,
118  const label hi,
119  const scalar lookUpValue,
120  const label ofield,
121  const label interfield
122 ) const
123 {
124  if
125  (
126  List<scalarField>::operator[](interfield).operator[](hi)
127  != List<scalarField>::operator[](interfield).operator[](lo)
128  )
129  {
130  scalar output
131  (
132  List<scalarField>::operator[](ofield).operator[](lo)
133  + (
134  List<scalarField>::operator[](ofield).operator[](hi)
135  - List<scalarField>::operator[](ofield).operator[](lo)
136  )
137  *(
138  lookUpValue
139  - List<scalarField>::operator[](interfield).operator[](lo)
140  )
141  /(
142  List<scalarField>::operator[](interfield).operator[](hi)
143  - List<scalarField>::operator[](interfield).operator[](lo)
144  )
145  );
146  return output;
147  }
148  else
149  {
150  return List<scalarField>::operator[](ofield).operator[](lo);
151  }
152 }
153 
154 
155 template<class Type>
157 {
158  min_.setSize(entries_.size());
159  dim_.setSize(entries_.size());
160  delta_.setSize(entries_.size());
161  max_.setSize(entries_.size());
162  entryIndices_.setSize(entries_.size());
163  outputIndices_.setSize(output_.size());
164  label index = 0;
165  label tableDim = 1;
166 
167  forAll(entries_,i)
168  {
169  dim_[i] = readLabel(entries_[i].lookup("N"));
170  max_[i] = readScalar(entries_[i].lookup("max"));
171  min_[i] = readScalar(entries_[i].lookup("min"));
172  delta_[i] = (max_[i] - min_[i])/dim_[i];
173  tableDim *= dim_[i] + 1;
174  fieldIndices_.insert(entries_[i].lookup("name"), index);
175  entryIndices_[i] = index;
176  index++;
177  }
178 
179  forAll(output_,i)
180  {
181  fieldIndices_.insert(output_[i].lookup("name"), index);
182  outputIndices_[i] = index;
183  index++;
184  }
185 
186  List<scalarField>& internal = *this;
187 
188  internal.setSize(entries_.size() + output_.size());
189 
190  interpOutput_.setSize(entries_.size() + output_.size());
191 
192  forAll(internal, i)
193  {
194  internal[i].setSize(tableDim);
195  }
196 }
197 
198 
199 template<class Type>
201 (
202  const word& instance,
203  const fvMesh& mesh
204 )
205 {
206  IOdictionary control
207  (
208  IOobject
209  (
210  fileName_,
211  instance,
212  mesh,
213  IOobject::MUST_READ,
214  IOobject::NO_WRITE
215  )
216  );
217 
218  control.lookup("fields") >> entries_;
219  control.lookup("output") >> output_;
220  control.lookup("values") >> *this;
221 
222  dimensionTable();
223 
224  check();
225 
226  if (this->size() == 0)
227  {
229  (
230  "Foam::interpolationLookUpTable<Type>::readTable()"
231  ) << "table is empty" << nl << exit(FatalError);
232  }
233 }
234 
235 
236 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
237 
238 template<class Type>
240 :
241  List<scalarField>(),
242  fileName_("fileNameIsUndefined")
243 {}
244 
245 
246 template<class Type>
248 (
249  const fileName& fn, const word& instance, const fvMesh& mesh
250 )
251 :
253  fileName_(fn),
254  dim_(0),
255  min_(0),
256  delta_(0.0),
257  max_(0.0),
258  entries_(0),
259  output_(0),
260  entryIndices_(0),
261  outputIndices_(0),
262  interpOutput_(0)
263 {
264  readTable(instance, mesh);
265 }
266 
267 
268 template<class Type>
270 (
271  const interpolationLookUpTable& interpTable
272 )
273 :
274  List<scalarField>(interpTable),
275  fileName_(interpTable.fileName_),
276  entryIndices_(interpTable.entryIndices_),
277  outputIndices_(interpTable.outputIndices_),
278  dim_(interpTable.dim_),
279  min_(interpTable.min_),
280  delta_(interpTable.delta_),
281  max_(interpTable.max_),
282  entries_(0),
283  output_(0),
284  interpOutput_(interpTable.interpOutput_)
285 {}
286 
287 
288 template<class Type>
290 (
291  const dictionary& dict
292 )
293 :
295  fileName_(fileName(dict.lookup("fileName")).expand()),
296  dim_(0),
297  min_(0.0),
298  delta_(0.0),
299  max_(0.0),
300  entries_(dict.lookup("fields")),
301  output_(dict.lookup("output")),
302  entryIndices_(0),
303  outputIndices_(0),
304  fieldIndices_(0),
305  interpOutput_(0)
306 {
307  dimensionTable();
308 }
309 
310 
311 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
312 
313 template<class Type>
315 {
316  // check order in the first dimension.
317  scalar prevValue = List<scalarField>::operator[](0).operator[](0);
318  label dim = 1;
319  for (int j = 1; j < dim_.size(); j++)
320  {
321  dim *= dim_[j] + 1;
322  }
323 
324  for (label i = 1; i < dim_[0]; i++)
325  {
326  label index = i*dim;
327  const scalar currValue =
328  List<scalarField>::operator[](0).operator[](index);
329 
330  // avoid duplicate values (divide-by-zero error)
331  if (currValue <= prevValue)
332  {
334  (
335  "Foam::interpolationLookUpTable<Type>::checkOrder() const"
336  ) << "out-of-order value: " << currValue
337  << " at index " << index << nl << exit(FatalError);
338  }
339  prevValue = currValue;
340  }
341 }
342 
343 
344 template<class Type>
346 (
347  Ostream& os,
348  const fileName& fn,
349  const word& instance,
350  const fvMesh& mesh
351 ) const
352 {
353  IOdictionary control
354  (
355  IOobject
356  (
357  fn,
358  instance,
359  mesh,
362  )
363  );
364 
365  control.writeHeader(os);
366 
367  os.writeKeyword("fields");
368  os << entries_ << token::END_STATEMENT << nl;
369 
370  os.writeKeyword("output");
371  os << output_ << token::END_STATEMENT << nl;
372 
373  if (this->size() == 0)
374  {
376  (
377  "Foam::interpolationTable<Type>::write()"
378  ) << "table is empty" << nl << exit(FatalError);
379  }
380  os.writeKeyword("values");
381  os << *this << token::END_STATEMENT << nl;
382 }
383 
384 
385 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
386 
387 template<class Type>
390 {
391  label ii = i;
392  label n = this->size();
393 
394  if (n <= 1)
395  {
397  (
398  "Foam::interpolationLookUpTable<Type>::operator[](const label)"
399  ) << "table has (" << n << ") columns" << nl << exit(FatalError);
400  }
401  else if (ii < 0)
402  {
404  (
405  "Foam::interpolationLookUpTable<Type>::operator[](const label)"
406  ) << "index (" << ii << ") underflow" << nl << exit(FatalError);
407  }
408  else if (ii > n)
409  {
411  (
412  "Foam::interpolationLookUpTable<Type>::operator[](const label)"
413  ) << "index (" << ii << ") overflow" << nl << exit(FatalError);
414  }
415 
417 }
418 
419 
420 template<class Type>
421 const Foam::scalarField&
423 {
424  label ii = i;
425  label n = this->size();
426 
427  if (n <= 1)
428  {
430  (
431  "Foam::interpolationLookUpTable<Type>::operator[]"
432  "(const label) const"
433  ) << "table has (" << n << ") columns" << nl << exit(FatalError);
434  }
435  else if (ii < 0)
436  {
438  (
439  "Foam::interpolationLookUpTable<Type>::operator[]"
440  "(const label) const"
441  ) << "index (" << ii << ") underflow" << nl << exit(FatalError);
442  }
443 
444  else if (ii > n)
445  {
447  (
448  "Foam::interpolationLookUpTable<Type>::operator[]"
449  "(const label) const"
450  ) << "index (" << ii << ") overflow" << nl
451  << exit(FatalError);
452  }
453 
455 }
456 
457 
458 template<class Type>
460 {
461  return fieldIndices_.found(fieldName);
462 }
463 
464 
465 template<class Type>
466 const Foam::scalarList&
468 {
469  const label lo = index(retvals);
470  findHi(lo, retvals);
471  return interpOutput_;
472 }
473 
474 
475 template<class Type>
477 (
478  const label lo,
479  const scalar retvals
480 )
481 {
482  forAll(outputIndices_,j)
483  {
484  scalar tmp = 0;
485  label ofield = outputIndices_[j];
486  scalar baseValue = List<scalarField>::operator[](ofield).operator[](lo);
487 
488  forAll(entryIndices_,i)
489  {
490  if (checkRange(retvals, entryIndices_[i]))
491  {
492  label dim = 1;
493 
494  label hi = Foam::min(lo + dim, (*this)[0].size() - 1);
495 
496  tmp += interpolate(lo, hi, retvals, ofield, entryIndices_[i])
497  - baseValue;
498  }
499  interpOutput_[entryIndices_[i]] = retvals;
500  }
501 
502  tmp += baseValue;
503  interpOutput_[outputIndices_[j]] = tmp;
504  }
505 }
506 
507 
508 // ************************ vim: set sw=4 sts=4 et: ************************ //