FreeFOAM The Cross-Platform CFD Toolkit
Hosted by SourceForge:
Get FreeFOAM at SourceForge.net.
            Fast, secure and Free Open Source software downloads

interpolationLookUpTable.C

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002   =========                 |
00003   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
00004    \\    /   O peration     |
00005     \\  /    A nd           | Copyright (C) 2008-2010 OpenCFD Ltd.
00006      \\/     M anipulation  |
00007 -------------------------------------------------------------------------------
00008 License
00009     This file is part of OpenFOAM.
00010 
00011     OpenFOAM is free software: you can redistribute it and/or modify it
00012     under the terms of the GNU General Public License as published by
00013     the Free Software Foundation, either version 3 of the License, or
00014     (at your option) any later version.
00015 
00016     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
00017     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00019     for more details.
00020 
00021     You should have received a copy of the GNU General Public License
00022     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
00023 
00024 \*---------------------------------------------------------------------------*/
00025 
00026 #include <OpenFOAM/IFstream.H>
00027 
00028 // * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * * //
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 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
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 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00312 
00313 template<class Type>
00314 void Foam::interpolationLookUpTable<Type>::check() const
00315 {
00316     // check order in the first dimension.
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         // avoid duplicate values (divide-by-zero error)
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 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
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 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines