1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2008-2010 OpenCFD Ltd.
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
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.
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
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/>.
24 \*---------------------------------------------------------------------------*/
27 // * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
30 Foam::label Foam::interpolationLookUpTable<Type>::index
32 const List<scalar>& indices,
41 for (int j = i + 1; j < dim_.size(); j++)
50 max(label((indices[i] - min_[i])/delta_[i]), 0),
57 label iLastdim = dim_.size() - 1;
58 totalIndex += Foam::min
62 label((indices[iLastdim] - min_[iLastdim])/delta_[iLastdim]),
74 Foam::label Foam::interpolationLookUpTable<Type>::index
85 label((indice - min_[i])/delta_[i]),
96 bool Foam::interpolationLookUpTable<Type>::checkRange
98 const scalar lookUpValue,
99 const label interfield
102 return lookUpValue >= min_[interfield] && lookUpValue <= max_[interfield];
107 Foam::scalar Foam::interpolationLookUpTable<Type>::interpolate
111 const scalar lookUpValue,
113 const label interfield
118 List<scalarField>::operator[](interfield).operator[](hi)
119 != List<scalarField>::operator[](interfield).operator[](lo)
124 List<scalarField>::operator[](ofield).operator[](lo)
126 List<scalarField>::operator[](ofield).operator[](hi)
127 - List<scalarField>::operator[](ofield).operator[](lo)
131 - List<scalarField>::operator[](interfield).operator[](lo)
134 List<scalarField>::operator[](interfield).operator[](hi)
135 - List<scalarField>::operator[](interfield).operator[](lo)
142 return List<scalarField>::operator[](ofield).operator[](lo);
148 void Foam::interpolationLookUpTable<Type>::dimensionTable()
150 min_.setSize(entries_.size());
151 dim_.setSize(entries_.size());
152 delta_.setSize(entries_.size());
153 max_.setSize(entries_.size());
154 entryIndices_.setSize(entries_.size());
155 outputIndices_.setSize(output_.size());
161 dim_[i] = readLabel(entries_[i].lookup("N"));
162 max_[i] = readScalar(entries_[i].lookup("max"));
163 min_[i] = readScalar(entries_[i].lookup("min"));
164 delta_[i] = (max_[i] - min_[i])/dim_[i];
165 tableDim *= dim_[i] + 1;
166 fieldIndices_.insert(entries_[i].lookup("name"), index);
167 entryIndices_[i] = index;
173 fieldIndices_.insert(output_[i].lookup("name"), index);
174 outputIndices_[i] = index;
178 List<scalarField>& internal = *this;
180 internal.setSize(entries_.size() + output_.size());
182 interpOutput_.setSize(entries_.size() + output_.size());
186 internal[i].setSize(tableDim);
192 void Foam::interpolationLookUpTable<Type>::readTable
194 const word& instance,
195 const objectRegistry& obr
205 IOobject::MUST_READ_IF_MODIFIED,
210 control.lookup("fields") >> entries_;
211 control.lookup("output") >> output_;
212 control.lookup("values") >> *this;
218 if (this->size() == 0)
222 "Foam::interpolationLookUpTable<Type>::readTable()"
223 ) << "table is empty" << nl << exit(FatalError);
228 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
231 Foam::interpolationLookUpTable<Type>::interpolationLookUpTable()
234 fileName_("fileNameIsUndefined")
239 Foam::interpolationLookUpTable<Type>::interpolationLookUpTable
242 const word& instance,
243 const objectRegistry& obr
258 readTable(instance, obr);
263 Foam::interpolationLookUpTable<Type>::interpolationLookUpTable
265 const interpolationLookUpTable& interpTable
268 List<scalarField>(interpTable),
269 fileName_(interpTable.fileName_),
270 entryIndices_(interpTable.entryIndices_),
271 outputIndices_(interpTable.outputIndices_),
272 dim_(interpTable.dim_),
273 min_(interpTable.min_),
274 delta_(interpTable.delta_),
275 max_(interpTable.max_),
278 interpOutput_(interpTable.interpOutput_)
283 Foam::interpolationLookUpTable<Type>::interpolationLookUpTable
285 const dictionary& dict
289 fileName_(fileName(dict.lookup("fileName")).expand()),
294 entries_(dict.lookup("fields")),
295 output_(dict.lookup("output")),
305 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
308 void Foam::interpolationLookUpTable<Type>::check() const
310 // check order in the first dimension.
311 scalar prevValue = List<scalarField>::operator[](0).operator[](0);
313 for (int j = 1; j < dim_.size(); j++)
318 for (label i = 1; i < dim_[0]; i++)
321 const scalar currValue =
322 List<scalarField>::operator[](0).operator[](index);
324 // avoid duplicate values (divide-by-zero error)
325 if (currValue <= prevValue)
329 "Foam::interpolationLookUpTable<Type>::checkOrder() const"
330 ) << "out-of-order value: " << currValue
331 << " at index " << index << nl << exit(FatalError);
333 prevValue = currValue;
339 void Foam::interpolationLookUpTable<Type>::write
343 const word& instance,
344 const objectRegistry& obr
359 control.writeHeader(os);
361 os.writeKeyword("fields")
362 << entries_ << token::END_STATEMENT << nl;
364 os.writeKeyword("output")
365 << output_ << token::END_STATEMENT << nl;
367 if (this->size() == 0)
371 "Foam::interpolationTable<Type>::write()"
372 ) << "table is empty" << nl << exit(FatalError);
374 os.writeKeyword("values")
375 << *this << token::END_STATEMENT << nl;
379 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
383 Foam::interpolationLookUpTable<Type>::operator[](const label i)
385 const label n = this->size();
391 "Foam::interpolationLookUpTable<Type>::operator[](const label)"
392 ) << "table has (" << n << ") columns" << nl << exit(FatalError);
398 "Foam::interpolationLookUpTable<Type>::operator[](const label)"
399 ) << "index (" << i << ") underflow" << nl << exit(FatalError);
405 "Foam::interpolationLookUpTable<Type>::operator[](const label)"
406 ) << "index (" << i << ") overflow" << nl << exit(FatalError);
409 return List<scalarField>::operator[](i);
414 const Foam::scalarField&
415 Foam::interpolationLookUpTable<Type>::operator[](const label i) const
417 const label n = this->size();
423 "Foam::interpolationLookUpTable<Type>::operator[]"
424 "(const label) const"
425 ) << "table has (" << n << ") columns" << nl << exit(FatalError);
431 "Foam::interpolationLookUpTable<Type>::operator[]"
432 "(const label) const"
433 ) << "index (" << i << ") underflow" << nl << exit(FatalError);
439 "Foam::interpolationLookUpTable<Type>::operator[]"
440 "(const label) const"
441 ) << "index (" << i << ") overflow" << nl
445 return List<scalarField>::operator[](i);
450 bool Foam::interpolationLookUpTable<Type>::found(const word& fieldName) const
452 return fieldIndices_.found(fieldName);
457 const Foam::scalarList&
458 Foam::interpolationLookUpTable<Type>::lookUp(const scalar retvals)
460 const label lo = index(retvals);
462 return interpOutput_;
467 void Foam::interpolationLookUpTable<Type>::findHi
473 forAll(outputIndices_,j)
476 label ofield = outputIndices_[j];
477 scalar baseValue = List<scalarField>::operator[](ofield).operator[](lo);
479 forAll(entryIndices_,i)
481 if (checkRange(retvals, entryIndices_[i]))
485 label hi = Foam::min(lo + dim, (*this)[0].size() - 1);
487 tmp += interpolate(lo, hi, retvals, ofield, entryIndices_[i])
490 interpOutput_[entryIndices_[i]] = retvals;
494 interpOutput_[outputIndices_[j]] = tmp;
499 // ************************************************************************* //