/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License This file is part of OpenFOAM. OpenFOAM is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. OpenFOAM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenFOAM. If not, see . \*---------------------------------------------------------------------------*/ #include "TableBase.H" #include "Time.H" #include "interpolationWeights.H" // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // template const Foam::interpolationWeights& Foam::TableBase::interpolator() const { if (interpolatorPtr_.empty()) { // Re-work table into linear list tableSamplesPtr_.reset(new scalarField(table_.size())); scalarField& tableSamples = tableSamplesPtr_(); forAll(table_, i) { tableSamples[i] = table_[i].first(); } interpolatorPtr_ = interpolationWeights::New ( interpolationScheme_, tableSamples ); } return interpolatorPtr_(); } // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // template Foam::TableBase::TableBase(const word& name, const dictionary& dict) : name_(name), boundsHandling_ ( wordToBoundsHandling ( dict.lookupOrDefault("outOfBounds", "clamp") ) ), interpolationScheme_ ( dict.lookupOrDefault("interpolationScheme", "linear") ), table_(), dimensions_(dimless) {} template Foam::TableBase::TableBase(const TableBase& tbl) : name_(tbl.name_), boundsHandling_(tbl.boundsHandling_), interpolationScheme_(tbl.interpolationScheme_), table_(tbl.table_), dimensions_(tbl.dimensions_), tableSamplesPtr_(tbl.tableSamplesPtr_), interpolatorPtr_(tbl.interpolatorPtr_) {} // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // template Foam::TableBase::~TableBase() {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // template Foam::word Foam::TableBase::boundsHandlingToWord ( const boundsHandling& bound ) const { word enumName("warn"); switch (bound) { case ERROR: { enumName = "error"; break; } case WARN: { enumName = "warn"; break; } case CLAMP: { enumName = "clamp"; break; } case REPEAT: { enumName = "repeat"; break; } } return enumName; } template typename Foam::TableBase::boundsHandling Foam::TableBase::wordToBoundsHandling ( const word& bound ) const { if (bound == "error") { return ERROR; } else if (bound == "warn") { return WARN; } else if (bound == "clamp") { return CLAMP; } else if (bound == "repeat") { return REPEAT; } else { WarningIn("Foam::TableBase::wordToBoundsHandling(const word&)") << "bad outOfBounds specifier " << bound << " using 'warn'" << endl; return WARN; } } template typename Foam::TableBase::boundsHandling Foam::TableBase::outOfBounds ( const boundsHandling& bound ) { boundsHandling prev = boundsHandling_; boundsHandling_ = bound; return prev; } template void Foam::TableBase::check() const { if (!table_.size()) { FatalErrorIn("Foam::TableBase::check() const") << "Table for entry " << this->name_ << " is invalid (empty)" << nl << exit(FatalError); } label n = table_.size(); scalar prevValue = table_[0].first(); for (label i = 1; i < n; ++i) { const scalar currValue = table_[i].first(); // avoid duplicate values (divide-by-zero error) if (currValue <= prevValue) { FatalErrorIn("Foam::TableBase::check() const") << "out-of-order value: " << currValue << " at index " << i << exit(FatalError); } prevValue = currValue; } } template bool Foam::TableBase::checkMinBounds ( const scalar x, scalar& xDash ) const { if (x < table_[0].first()) { switch (boundsHandling_) { case ERROR: { FatalErrorIn ( "bool Foam::TableBase::checkMinBounds" "(" "const scalar, " "scalar&" ") const" ) << "value (" << x << ") underflow" << exit(FatalError); break; } case WARN: { WarningIn ( "bool Foam::TableBase::checkMinBounds" "(" "const scalar, " "scalar&" ") const" ) << "value (" << x << ") underflow" << nl << endl; // fall-through to 'CLAMP' } case CLAMP: { xDash = table_[0].first(); return true; break; } case REPEAT: { // adjust x to >= minX scalar span = table_.last().first() - table_[0].first(); xDash = fmod(x - table_[0].first(), span) + table_[0].first(); break; } } } else { xDash = x; } return false; } template bool Foam::TableBase::checkMaxBounds ( const scalar x, scalar& xDash ) const { if (x > table_.last().first()) { switch (boundsHandling_) { case ERROR: { FatalErrorIn ( "bool Foam::TableBase::checkMaxBounds" "(" "const scalar, " "scalar&" ") const" ) << "value (" << x << ") overflow" << exit(FatalError); break; } case WARN: { WarningIn ( "bool Foam::TableBase::checkMaxBounds" "(" "const scalar, " "scalar&" ") const" ) << "value (" << x << ") overflow" << nl << endl; // fall-through to 'CLAMP' } case CLAMP: { xDash = table_.last().first(); return true; break; } case REPEAT: { // adjust x to >= minX scalar span = table_.last().first() - table_[0].first(); xDash = fmod(x - table_[0].first(), span) + table_[0].first(); break; } } } else { xDash = x; } return false; } template void Foam::TableBase::convertTimeBase(const Time& t) { forAll(table_, i) { scalar value = table_[i].first(); table_[i].first() = t.userTimeToTime(value); } tableSamplesPtr_.clear(); interpolatorPtr_.clear(); } template Type Foam::TableBase::value(const scalar x) const { scalar xDash = x; if (checkMinBounds(x, xDash)) { return table_[0].second(); } if (checkMaxBounds(xDash, xDash)) { return table_.last().second(); } // Use interpolator interpolator().valueWeights(xDash, currentIndices_, currentWeights_); Type t = currentWeights_[0]*table_[currentIndices_[0]].second(); for (label i = 1; i < currentIndices_.size(); i++) { t += currentWeights_[i]*table_[currentIndices_[i]].second(); } return t; } template Type Foam::TableBase::integrate(const scalar x1, const scalar x2) const { // Use interpolator interpolator().integrationWeights(x1, x2, currentIndices_, currentWeights_); Type sum = currentWeights_[0]*table_[currentIndices_[0]].second(); for (label i = 1; i < currentIndices_.size(); i++) { sum += currentWeights_[i]*table_[currentIndices_[i]].second(); } return sum; } template Foam::dimensioned Foam::TableBase:: dimValue(const scalar x) const { return dimensioned("dimensionedValue", dimensions_, this->value(x)); } template Foam::dimensioned Foam::TableBase::dimIntegrate ( const scalar x1, const scalar x2 ) const { return dimensioned ( "dimensionedValue", dimensions_, this->integrate(x2, x1) ); } template Foam::tmp Foam::TableBase::x() const { tmp tfld(new scalarField(table_.size(), 0.0)); scalarField& fld = tfld(); forAll(table_, i) { fld[i] = table_[i].first(); } return tfld; } template Foam::tmp > Foam::TableBase::y() const { tmp > tfld(new Field(table_.size(), pTraits::zero)); Field& fld = tfld(); forAll(table_, i) { fld[i] = table_[i].second(); } return tfld; } // * * * * * * * * * * * * * * IOStream operators * * * * * * * * * * * * * // #include "TableBaseIO.C" // ************************************************************************* //