From 1df679963e30631d4222c2ce2d3f91f1f9ab2eb0 Mon Sep 17 00:00:00 2001 From: andy <andy> Date: Tue, 22 Nov 2011 13:14:19 +0000 Subject: [PATCH] ENH: Added base class for DataEntry table-types --- .../functions/DataEntry/Table/TableBase.C | 399 ++++++++++++++++++ .../functions/DataEntry/Table/TableBase.H | 167 ++++++++ .../functions/DataEntry/Table/TableBaseIO.C | 67 +++ 3 files changed, 633 insertions(+) create mode 100644 src/OpenFOAM/primitives/functions/DataEntry/Table/TableBase.C create mode 100644 src/OpenFOAM/primitives/functions/DataEntry/Table/TableBase.H create mode 100644 src/OpenFOAM/primitives/functions/DataEntry/Table/TableBaseIO.C diff --git a/src/OpenFOAM/primitives/functions/DataEntry/Table/TableBase.C b/src/OpenFOAM/primitives/functions/DataEntry/Table/TableBase.C new file mode 100644 index 00000000000..b25f8144853 --- /dev/null +++ b/src/OpenFOAM/primitives/functions/DataEntry/Table/TableBase.C @@ -0,0 +1,399 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011 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 <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "TableBase.H" + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +template<class Type> +Foam::TableBase<Type>::TableBase(const word& name, const dictionary& dict) +: + name_(name), + boundsHandling_ + ( + wordToBoundsHandling + ( + dict.lookupOrDefault<word>("outOfBounds", "warn") + ) + ), + table_() +{} + + +template<class Type> +Foam::TableBase<Type>::TableBase(const TableBase<Type>& tbl) +: + name_(tbl.name_), + boundsHandling_(tbl.boundsHandling_), + table_(tbl.table_) +{} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +template<class Type> +Foam::TableBase<Type>::~TableBase() +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template<class Type> +Foam::word Foam::TableBase<Type>::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<class Type> +typename Foam::TableBase<Type>::boundsHandling +Foam::TableBase<Type>::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<Type>::wordToBoundsHandling(const word&)") + << "bad outOfBounds specifier " << bound << " using 'warn'" + << endl; + + return WARN; + } +} + + +template<class Type> +typename Foam::TableBase<Type>::boundsHandling +Foam::TableBase<Type>::outOfBounds +( + const boundsHandling& bound +) +{ + boundsHandling prev = boundsHandling_; + boundsHandling_ = bound; + return prev; +} + + +template<class Type> +void Foam::TableBase<Type>::check() const +{ + if (!table_.size()) + { + FatalErrorIn("Foam::TableBase<Type>::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<Type>::check() const") + << "out-of-order value: " << currValue << " at index " << i + << exit(FatalError); + } + prevValue = currValue; + } +} + + +template<class Type> +bool Foam::TableBase<Type>::checkMinBounds +( + const scalar x, + scalar& xDash +) const +{ + if (x < table_[0].first()) + { + switch (boundsHandling_) + { + case ERROR: + { + FatalErrorIn + ( + "bool Foam::TableBase<Type>::checkMinBounds" + "(" + "const scalar, " + "scalar&" + ") const" + ) << "value (" << x << ") underflow" + << exit(FatalError); + break; + } + case WARN: + { + WarningIn + ( + "bool Foam::TableBase<Type>::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<class Type> +bool Foam::TableBase<Type>::checkMaxBounds +( + const scalar x, + scalar& xDash +) const +{ + if (x < table_.last().first()) + { + switch (boundsHandling_) + { + case ERROR: + { + FatalErrorIn + ( + "bool Foam::TableBase<Type>::checkMaxBounds" + "(" + "const scalar, " + "scalar&" + ") const" + ) << "value (" << x << ") overflow" + << exit(FatalError); + break; + } + case WARN: + { + WarningIn + ( + "bool Foam::TableBase<Type>::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<class Type> +Type Foam::TableBase<Type>::value(const scalar x) const +{ + scalar xDash = x; + + if (checkMinBounds(x, xDash)) + { + return table_[0].second(); + } + + if (checkMaxBounds(xDash, xDash)) + { + return table_.last().second(); + } + + // Find i such that x(i) < xDash < x(i+1) + label i = 0; + while ((table_[i+1].first() < xDash) && (i+1 < table_.size())) + { + i++; + } + + // Linear interpolation to find value + return Type + ( + (xDash - table_[i].first())/(table_[i+1].first() - table_[i].first()) + * (table_[i+1].second() - table_[i].second()) + + table_[i].second() + ); +} + + +template<class Type> +Type Foam::TableBase<Type>::integrate(const scalar x1, const scalar x2) const +{ + // Initialise return value + Type sum = pTraits<Type>::zero; + + // Return zero if out of bounds + if ((x1 > table_.last().first()) || (x2 < table_[0].first())) + { + return sum; + } + + // Find next index greater than x1 + label id1 = 0; + while ((table_[id1].first() < x1) && (id1 < table_.size())) + { + id1++; + } + + // Find next index less than x2 + label id2 = table_.size() - 1; + while ((table_[id2].first() > x2) && (id2 >= 1)) + { + id2--; + } + + if ((id1 - id2) == 1) + { + // x1 and x2 lie within 1 interval + sum = 0.5*(value(x1) + value(x2))*(x2 - x1); + } + else + { + // x1 and x2 cross multiple intervals + + // Integrate table body + for (label i=id1; i<id2; i++) + { + sum += + (table_[i].second() + table_[i+1].second()) + * (table_[i+1].first() - table_[i].first()); + } + sum *= 0.5; + + // Add table ends (partial segments) + if (id1 > 0) + { + sum += 0.5 + * (value(x1) + table_[id1].second()) + * (table_[id1].first() - x1); + } + if (id2 < table_.size() - 1) + { + sum += 0.5 + * (table_[id2].second() + value(x2)) + * (x2 - table_[id2].first()); + } + } + + return sum; +} + + +// * * * * * * * * * * * * * * IOStream operators * * * * * * * * * * * * * // + +#include "TableBaseIO.C" + + +// ************************************************************************* // diff --git a/src/OpenFOAM/primitives/functions/DataEntry/Table/TableBase.H b/src/OpenFOAM/primitives/functions/DataEntry/Table/TableBase.H new file mode 100644 index 00000000000..82ee7e697a9 --- /dev/null +++ b/src/OpenFOAM/primitives/functions/DataEntry/Table/TableBase.H @@ -0,0 +1,167 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011 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 <http://www.gnu.org/licenses/>. + +Class + Foam::TableBase + +Description + Base class for table with bounds handling, interpolation and integration + +SourceFiles + TableBase.C + +\*---------------------------------------------------------------------------*/ + +#ifndef TableBase_H +#define TableBase_H + +#include "DataEntry.H" +#include "Tuple2.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +template<class Type> +class TableBase; + +template<class Type> +Ostream& operator<< +( + Ostream&, + const TableBase<Type>& +); + +/*---------------------------------------------------------------------------*\ + Class TableBase Declaration +\*---------------------------------------------------------------------------*/ + +template<class Type> +class TableBase +{ +public: + + // Public data types + + //- Enumeration for handling out-of-bound values + enum boundsHandling + { + ERROR, /*!< Exit with a FatalError */ + WARN, /*!< Issue warning and clamp value (default) */ + CLAMP, /*!< Clamp value to the start/end value */ + REPEAT /*!< Treat as a repeating list */ + }; + + +protected: + + // Protected data + + //- Table name + word name_; + + //- Enumeration for handling out-of-bound values + boundsHandling boundsHandling_; + + //- Table data + List<Tuple2<scalar, Type> > table_; + + + // Protected Member Functions + + //- Disallow default bitwise assignment + void operator=(const TableBase<Type>&); + + +public: + + // Constructors + + //- Construct from dictionary - note table is not populated + TableBase(const word& name, const dictionary& dict); + + //- Copy constructor + TableBase(const TableBase<Type>& tbl); + + + //- Destructor + virtual ~TableBase(); + + + // Member Functions + + //- Return the out-of-bounds handling as a word + word boundsHandlingToWord(const boundsHandling& bound) const; + + //- Return the out-of-bounds handling as an enumeration + boundsHandling wordToBoundsHandling(const word& bound) const; + + //- Set the out-of-bounds handling from enum, return previous setting + boundsHandling outOfBounds(const boundsHandling& bound); + + //- Check the table for size and consistency + void check() const; + + //- Check minimum table bounds + bool checkMinBounds(const scalar x, scalar& xDash) const; + + //- Check maximum table bounds + bool checkMaxBounds(const scalar x, scalar& xDash) const; + + //- Return Table value + Type value(const scalar x) const; + + //- Integrate between two (scalar) values + Type integrate(const scalar x1, const scalar x2) const; + + + // I/O + + //- Ostream Operator + friend Ostream& operator<< <Type> + ( + Ostream& os, + const TableBase<Type>& tbl + ); + + //- Write in dictionary format + virtual void writeData(Ostream& os) const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository +# include "TableBase.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/OpenFOAM/primitives/functions/DataEntry/Table/TableBaseIO.C b/src/OpenFOAM/primitives/functions/DataEntry/Table/TableBaseIO.C new file mode 100644 index 00000000000..438c657a8f1 --- /dev/null +++ b/src/OpenFOAM/primitives/functions/DataEntry/Table/TableBaseIO.C @@ -0,0 +1,67 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011 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 <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "DataEntry.H" + +// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * // + +template<class Type> +Foam::Ostream& Foam::operator<< +( + Ostream& os, + const TableBase<Type>& tbl +) +{ + if (os.format() == IOstream::ASCII) + { + os << token::SPACE << tbl.table_; + } + else + { + os.write + ( + reinterpret_cast<const char*>(&tbl.table_), + sizeof(tbl.table_) + ); + } + + // Check state of Ostream + os.check + ( + "Ostream& operator<<(Ostream&, const TableBase<Type>&, const bool)" + ); + + return os; +} + + +template<class Type> +void Foam::TableBase<Type>::writeData(Ostream& os) const +{ + os << nl << indent << table_ << token::END_STATEMENT << nl; +} + + +// ************************************************************************* // -- GitLab