00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <OpenFOAM/IFstream.H>
00027
00028
00029
00030 template <class Type>
00031 Foam::label Foam::interpolationLookUpTable<Type>::index
00032 (
00033 const List<scalar>& indices,
00034 const bool lastDim
00035 ) const
00036 {
00037 label totalIndex = 0;
00038
00039 forAll(dim_, i)
00040 {
00041 label dim = 1;
00042 for (int j = i + 1; j < dim_.size(); j++)
00043 {
00044 dim *= dim_[j] + 1;
00045 }
00046
00047 totalIndex +=
00048 dim
00049 *min
00050 (
00051 max(label((indices[i] - min_[i])/delta_[i]), 0),
00052 dim_[i]
00053 );
00054 }
00055
00056 if (lastDim)
00057 {
00058 label iLastdim = dim_.size() - 1;
00059 totalIndex += Foam::min
00060 (
00061 max
00062 (
00063 label((indices[iLastdim] - min_[iLastdim])/delta_[iLastdim]),
00064 0
00065 ),
00066 dim_[iLastdim]
00067 );
00068 }
00069
00070 return totalIndex;
00071 }
00072
00073
00074 template <class Type>
00075 Foam::label Foam::interpolationLookUpTable<Type>::index
00076 (
00077 const scalar indice
00078 ) const
00079 {
00080 label i = 0;
00081 label totalIndex =
00082 Foam::min
00083 (
00084 Foam::max
00085 (
00086 label((indice - min_[i])/delta_[i]),
00087 0
00088 ),
00089 dim_[i]
00090 );
00091
00092 return totalIndex;
00093 }
00094
00095
00096 template<class Type>
00097 bool Foam::interpolationLookUpTable<Type>::checkRange
00098 (
00099 const scalar lookUpValue,
00100 const label interfield
00101 ) const
00102 {
00103 if (lookUpValue >= min_[interfield] && lookUpValue <= max_[interfield])
00104 {
00105 return true;
00106 }
00107 else
00108 {
00109 return false;
00110 }
00111 }
00112
00113
00114 template<class Type>
00115 Foam::scalar Foam::interpolationLookUpTable<Type>::interpolate
00116 (
00117 const label lo,
00118 const label hi,
00119 const scalar lookUpValue,
00120 const label ofield,
00121 const label interfield
00122 ) const
00123 {
00124 if
00125 (
00126 List<scalarField>::operator[](interfield).operator[](hi)
00127 != List<scalarField>::operator[](interfield).operator[](lo)
00128 )
00129 {
00130 scalar output
00131 (
00132 List<scalarField>::operator[](ofield).operator[](lo)
00133 + (
00134 List<scalarField>::operator[](ofield).operator[](hi)
00135 - List<scalarField>::operator[](ofield).operator[](lo)
00136 )
00137 *(
00138 lookUpValue
00139 - List<scalarField>::operator[](interfield).operator[](lo)
00140 )
00141 /(
00142 List<scalarField>::operator[](interfield).operator[](hi)
00143 - List<scalarField>::operator[](interfield).operator[](lo)
00144 )
00145 );
00146 return output;
00147 }
00148 else
00149 {
00150 return List<scalarField>::operator[](ofield).operator[](lo);
00151 }
00152 }
00153
00154
00155 template<class Type>
00156 void Foam::interpolationLookUpTable<Type>::dimensionTable()
00157 {
00158 min_.setSize(entries_.size());
00159 dim_.setSize(entries_.size());
00160 delta_.setSize(entries_.size());
00161 max_.setSize(entries_.size());
00162 entryIndices_.setSize(entries_.size());
00163 outputIndices_.setSize(output_.size());
00164 label index = 0;
00165 label tableDim = 1;
00166
00167 forAll(entries_,i)
00168 {
00169 dim_[i] = readLabel(entries_[i].lookup("N"));
00170 max_[i] = readScalar(entries_[i].lookup("max"));
00171 min_[i] = readScalar(entries_[i].lookup("min"));
00172 delta_[i] = (max_[i] - min_[i])/dim_[i];
00173 tableDim *= dim_[i] + 1;
00174 fieldIndices_.insert(entries_[i].lookup("name"), index);
00175 entryIndices_[i] = index;
00176 index++;
00177 }
00178
00179 forAll(output_,i)
00180 {
00181 fieldIndices_.insert(output_[i].lookup("name"), index);
00182 outputIndices_[i] = index;
00183 index++;
00184 }
00185
00186 List<scalarField>& internal = *this;
00187
00188 internal.setSize(entries_.size() + output_.size());
00189
00190 interpOutput_.setSize(entries_.size() + output_.size());
00191
00192 forAll(internal, i)
00193 {
00194 internal[i].setSize(tableDim);
00195 }
00196 }
00197
00198
00199 template<class Type>
00200 void Foam::interpolationLookUpTable<Type>::readTable
00201 (
00202 const word& instance,
00203 const fvMesh& mesh
00204 )
00205 {
00206 IOdictionary control
00207 (
00208 IOobject
00209 (
00210 fileName_,
00211 instance,
00212 mesh,
00213 IOobject::MUST_READ,
00214 IOobject::NO_WRITE
00215 )
00216 );
00217
00218 control.lookup("fields") >> entries_;
00219 control.lookup("output") >> output_;
00220 control.lookup("values") >> *this;
00221
00222 dimensionTable();
00223
00224 check();
00225
00226 if (this->size() == 0)
00227 {
00228 FatalErrorIn
00229 (
00230 "Foam::interpolationLookUpTable<Type>::readTable()"
00231 ) << "table is empty" << nl << exit(FatalError);
00232 }
00233 }
00234
00235
00236
00237
00238 template<class Type>
00239 Foam::interpolationLookUpTable<Type>::interpolationLookUpTable()
00240 :
00241 List<scalarField>(),
00242 fileName_("fileNameIsUndefined")
00243 {}
00244
00245
00246 template<class Type>
00247 Foam::interpolationLookUpTable<Type>::interpolationLookUpTable
00248 (
00249 const fileName& fn, const word& instance, const fvMesh& mesh
00250 )
00251 :
00252 List<scalarField>(),
00253 fileName_(fn),
00254 dim_(0),
00255 min_(0),
00256 delta_(0.0),
00257 max_(0.0),
00258 entries_(0),
00259 output_(0),
00260 entryIndices_(0),
00261 outputIndices_(0),
00262 interpOutput_(0)
00263 {
00264 readTable(instance, mesh);
00265 }
00266
00267
00268 template<class Type>
00269 Foam::interpolationLookUpTable<Type>::interpolationLookUpTable
00270 (
00271 const interpolationLookUpTable& interpTable
00272 )
00273 :
00274 List<scalarField>(interpTable),
00275 fileName_(interpTable.fileName_),
00276 entryIndices_(interpTable.entryIndices_),
00277 outputIndices_(interpTable.outputIndices_),
00278 dim_(interpTable.dim_),
00279 min_(interpTable.min_),
00280 delta_(interpTable.delta_),
00281 max_(interpTable.max_),
00282 entries_(0),
00283 output_(0),
00284 interpOutput_(interpTable.interpOutput_)
00285 {}
00286
00287
00288 template<class Type>
00289 Foam::interpolationLookUpTable<Type>::interpolationLookUpTable
00290 (
00291 const dictionary& dict
00292 )
00293 :
00294 List<scalarField>(),
00295 fileName_(fileName(dict.lookup("fileName")).expand()),
00296 dim_(0),
00297 min_(0.0),
00298 delta_(0.0),
00299 max_(0.0),
00300 entries_(dict.lookup("fields")),
00301 output_(dict.lookup("output")),
00302 entryIndices_(0),
00303 outputIndices_(0),
00304 fieldIndices_(0),
00305 interpOutput_(0)
00306 {
00307 dimensionTable();
00308 }
00309
00310
00311
00312
00313 template<class Type>
00314 void Foam::interpolationLookUpTable<Type>::check() const
00315 {
00316
00317 scalar prevValue = List<scalarField>::operator[](0).operator[](0);
00318 label dim = 1;
00319 for (int j = 1; j < dim_.size(); j++)
00320 {
00321 dim *= dim_[j] + 1;
00322 }
00323
00324 for (label i = 1; i < dim_[0]; i++)
00325 {
00326 label index = i*dim;
00327 const scalar currValue =
00328 List<scalarField>::operator[](0).operator[](index);
00329
00330
00331 if (currValue <= prevValue)
00332 {
00333 FatalErrorIn
00334 (
00335 "Foam::interpolationLookUpTable<Type>::checkOrder() const"
00336 ) << "out-of-order value: " << currValue
00337 << " at index " << index << nl << exit(FatalError);
00338 }
00339 prevValue = currValue;
00340 }
00341 }
00342
00343
00344 template<class Type>
00345 void Foam::interpolationLookUpTable<Type>::write
00346 (
00347 Ostream& os,
00348 const fileName& fn,
00349 const word& instance,
00350 const fvMesh& mesh
00351 ) const
00352 {
00353 IOdictionary control
00354 (
00355 IOobject
00356 (
00357 fn,
00358 instance,
00359 mesh,
00360 IOobject::NO_READ,
00361 IOobject::NO_WRITE
00362 )
00363 );
00364
00365 control.writeHeader(os);
00366
00367 os.writeKeyword("fields");
00368 os << entries_ << token::END_STATEMENT << nl;
00369
00370 os.writeKeyword("output");
00371 os << output_ << token::END_STATEMENT << nl;
00372
00373 if (this->size() == 0)
00374 {
00375 FatalErrorIn
00376 (
00377 "Foam::interpolationTable<Type>::write()"
00378 ) << "table is empty" << nl << exit(FatalError);
00379 }
00380 os.writeKeyword("values");
00381 os << *this << token::END_STATEMENT << nl;
00382 }
00383
00384
00385
00386
00387 template<class Type>
00388 Foam::scalarField&
00389 Foam::interpolationLookUpTable<Type>::operator[](const label i)
00390 {
00391 label ii = i;
00392 label n = this->size();
00393
00394 if (n <= 1)
00395 {
00396 FatalErrorIn
00397 (
00398 "Foam::interpolationLookUpTable<Type>::operator[](const label)"
00399 ) << "table has (" << n << ") columns" << nl << exit(FatalError);
00400 }
00401 else if (ii < 0)
00402 {
00403 FatalErrorIn
00404 (
00405 "Foam::interpolationLookUpTable<Type>::operator[](const label)"
00406 ) << "index (" << ii << ") underflow" << nl << exit(FatalError);
00407 }
00408 else if (ii > n)
00409 {
00410 FatalErrorIn
00411 (
00412 "Foam::interpolationLookUpTable<Type>::operator[](const label)"
00413 ) << "index (" << ii << ") overflow" << nl << exit(FatalError);
00414 }
00415
00416 return List<scalarField>::operator[](ii);
00417 }
00418
00419
00420 template<class Type>
00421 const Foam::scalarField&
00422 Foam::interpolationLookUpTable<Type>::operator[](const label i) const
00423 {
00424 label ii = i;
00425 label n = this->size();
00426
00427 if (n <= 1)
00428 {
00429 FatalErrorIn
00430 (
00431 "Foam::interpolationLookUpTable<Type>::operator[]"
00432 "(const label) const"
00433 ) << "table has (" << n << ") columns" << nl << exit(FatalError);
00434 }
00435 else if (ii < 0)
00436 {
00437 FatalErrorIn
00438 (
00439 "Foam::interpolationLookUpTable<Type>::operator[]"
00440 "(const label) const"
00441 ) << "index (" << ii << ") underflow" << nl << exit(FatalError);
00442 }
00443
00444 else if (ii > n)
00445 {
00446 FatalErrorIn
00447 (
00448 "Foam::interpolationLookUpTable<Type>::operator[]"
00449 "(const label) const"
00450 ) << "index (" << ii << ") overflow" << nl
00451 << exit(FatalError);
00452 }
00453
00454 return List<scalarField>::operator[](ii);
00455 }
00456
00457
00458 template<class Type>
00459 bool Foam::interpolationLookUpTable<Type>::found(const word& fieldName) const
00460 {
00461 return fieldIndices_.found(fieldName);
00462 }
00463
00464
00465 template<class Type>
00466 const Foam::scalarList&
00467 Foam::interpolationLookUpTable<Type>::lookUp(const scalar retvals)
00468 {
00469 const label lo = index(retvals);
00470 findHi(lo, retvals);
00471 return interpOutput_;
00472 }
00473
00474
00475 template<class Type>
00476 void Foam::interpolationLookUpTable<Type>::findHi
00477 (
00478 const label lo,
00479 const scalar retvals
00480 )
00481 {
00482 forAll(outputIndices_,j)
00483 {
00484 scalar tmp = 0;
00485 label ofield = outputIndices_[j];
00486 scalar baseValue = List<scalarField>::operator[](ofield).operator[](lo);
00487
00488 forAll(entryIndices_,i)
00489 {
00490 if (checkRange(retvals, entryIndices_[i]))
00491 {
00492 label dim = 1;
00493
00494 label hi = Foam::min(lo + dim, (*this)[0].size() - 1);
00495
00496 tmp += interpolate(lo, hi, retvals, ofield, entryIndices_[i])
00497 - baseValue;
00498 }
00499 interpOutput_[entryIndices_[i]] = retvals;
00500 }
00501
00502 tmp += baseValue;
00503 interpOutput_[outputIndices_[j]] = tmp;
00504 }
00505 }
00506
00507
00508