Commit bf7f5e62 authored by Henry's avatar Henry
Browse files

PolynomialEntry: Templated polynomial DataEntry to support all basic field...

PolynomialEntry: Templated polynomial DataEntry to support all basic field types from scalar to tensor
This allows polynomial functions for e.g. velocity to be specified in the uniformFixedValue BC

Consider a linear function for Ux(t) with Uy and Uz = 0:

    inlet
    {
        type            uniformFixedValue;
        uniformValue    polynomial
        (
            ((10 0 0)   (0 0 0))
            ((100 0 0)  (1 0 0))
        );
    }

Resolves bug report http://www.openfoam.org/mantisbt/view.php?id=1508
parent e22b220c
......@@ -73,8 +73,6 @@ primitives/triad/triad.C
/* functions, data entries */
primitives/functions/DataEntry/makeDataEntries.C
primitives/functions/DataEntry/polynomial/polynomial.C
primitives/functions/DataEntry/polynomial/polynomialIO.C
primitives/functions/Polynomial/polynomialFunction.C
......
......@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
......@@ -226,6 +226,12 @@ inline Scalar cmptMultiply(const Scalar s1, const Scalar s2)
}
inline Scalar cmptPow(const Scalar s1, const Scalar s2)
{
return pow(s1, s2);
}
inline Scalar cmptDivide(const Scalar s1, const Scalar s2)
{
return s1/s2;
......
......@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
......@@ -346,6 +346,19 @@ inline VectorSpace<Form, Cmpt, nCmpt> cmptMultiply
}
template<class Form, class Cmpt, int nCmpt>
inline VectorSpace<Form, Cmpt, nCmpt> cmptPow
(
const VectorSpace<Form, Cmpt, nCmpt>& vs1,
const VectorSpace<Form, Cmpt, nCmpt>& vs2
)
{
Form v;
VectorSpaceOps<nCmpt,0>::op(v, vs1, vs2, cmptPowOp<Cmpt>());
return v;
}
template<class Form, class Cmpt, int nCmpt>
inline VectorSpace<Form, Cmpt, nCmpt> cmptDivide
(
......
......@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
......@@ -31,7 +31,20 @@ License
namespace Foam
{
// doesn't recognize specialization otherwise
template<>
label CSV<label>::readValue(const List<string>& splitted)
{
if (componentColumns_[0] >= splitted.size())
{
FatalErrorIn("CSV<label>::readValue(const List<string>&)")
<< "No column " << componentColumns_[0] << " in "
<< splitted << endl
<< exit(FatalError);
}
return readLabel(IStringStream(splitted[componentColumns_[0]])());
}
template<>
scalar CSV<scalar>::readValue(const List<string>& splitted)
{
......
......@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
......@@ -103,6 +103,7 @@ Foam::dimensioned<Type> Foam::Constant<Type>::dimIntegrate
return dimensioned<Type>("dimensionedValue", dimensions_, (x2-x1)*value_);
}
// * * * * * * * * * * * * * * IOStream operators * * * * * * * * * * * * * //
#include "ConstantIO.C"
......
......@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
......@@ -23,7 +23,7 @@ License
\*---------------------------------------------------------------------------*/
#include "DataEntry.H"
#include "Constant.H"
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
......
......@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
......@@ -23,24 +23,18 @@ License
\*---------------------------------------------------------------------------*/
#include "polynomial.H"
#include "Time.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(polynomial, 0);
addToRunTimeSelectionTable(scalarDataEntry, polynomial, dictionary);
}
#include "PolynomialEntry.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::polynomial::polynomial(const word& entryName, const dictionary& dict)
template<class Type>
Foam::PolynomialEntry<Type>::PolynomialEntry
(
const word& entryName,
const dictionary& dict
)
:
scalarDataEntry(entryName),
DataEntry<Type>(entryName),
coeffs_(),
canIntegrate_(true),
dimensions_(dimless)
......@@ -61,14 +55,15 @@ Foam::polynomial::polynomial(const word& entryName, const dictionary& dict)
{
FatalErrorIn
(
"Foam::polynomial::polynomial(const word&, const dictionary&)"
) << "polynomial coefficients for entry " << this->name_
"PolynomialEntry<Type>::"
"PolynomialEntry(const word&, const dictionary&)"
) << "PolynomialEntry coefficients for entry " << this->name_
<< " are invalid (empty)" << nl << exit(FatalError);
}
forAll(coeffs_, i)
{
if (mag(coeffs_[i].second() + 1) < ROOTVSMALL)
if (mag(coeffs_[i].second() + pTraits<Type>::one) < ROOTVSMALL)
{
canIntegrate_ = false;
break;
......@@ -81,21 +76,23 @@ Foam::polynomial::polynomial(const word& entryName, const dictionary& dict)
{
WarningIn
(
"Foam::polynomial::polynomial(const word&, const dictionary&)"
) << "Polynomial " << this->name_ << " cannot be integrated"
"PolynomialEntry<Type>::PolynomialEntry"
"(const word&, const dictionary&)"
) << "PolynomialEntry " << this->name_ << " cannot be integrated"
<< endl;
}
}
}
Foam::polynomial::polynomial
template<class Type>
Foam::PolynomialEntry<Type>::PolynomialEntry
(
const word& entryName,
const List<Tuple2<scalar, scalar> >& coeffs
const List<Tuple2<Type, Type> >& coeffs
)
:
scalarDataEntry(entryName),
DataEntry<Type>(entryName),
coeffs_(coeffs),
canIntegrate_(true),
dimensions_(dimless)
......@@ -104,9 +101,9 @@ Foam::polynomial::polynomial
{
FatalErrorIn
(
"Foam::polynomial::polynomial"
"(const word&, const List<Tuple2<scalar, scalar> >&)"
) << "polynomial coefficients for entry " << this->name_
"Foam::PolynomialEntry<Type>::PolynomialEntry"
"(const word&, const List<Tuple2<Type, Type> >&)"
) << "PolynomialEntry coefficients for entry " << this->name_
<< " are invalid (empty)" << nl << exit(FatalError);
}
......@@ -125,18 +122,19 @@ Foam::polynomial::polynomial
{
WarningIn
(
"Foam::polynomial::polynomial"
"(const word&, const List<Tuple2<scalar, scalar> >&)"
) << "Polynomial " << this->name_ << " cannot be integrated"
"Foam::PolynomialEntry<Type>::PolynomialEntry"
"(const word&, const List<Tuple2<Type, Type> >&)"
) << "PolynomialEntry " << this->name_ << " cannot be integrated"
<< endl;
}
}
}
Foam::polynomial::polynomial(const polynomial& poly)
template<class Type>
Foam::PolynomialEntry<Type>::PolynomialEntry(const PolynomialEntry& poly)
:
scalarDataEntry(poly),
DataEntry<Type>(poly),
coeffs_(poly.coeffs_),
canIntegrate_(poly.canIntegrate_),
dimensions_(poly.dimensions_)
......@@ -145,48 +143,76 @@ Foam::polynomial::polynomial(const polynomial& poly)
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::polynomial::~polynomial()
template<class Type>
Foam::PolynomialEntry<Type>::~PolynomialEntry()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::polynomial::convertTimeBase(const Time& t)
template<class Type>
void Foam::PolynomialEntry<Type>::convertTimeBase(const Time& t)
{
forAll(coeffs_, i)
{
scalar value = coeffs_[i].first();
coeffs_[i].first() = t.userTimeToTime(value);
Type value = coeffs_[i].first();
for (direction cmpt = 0; cmpt < pTraits<Type>::nComponents; cmpt++)
{
setComponent(coeffs_[i].first(), cmpt) =
t.userTimeToTime(component(value, cmpt));
}
}
}
Foam::scalar Foam::polynomial::value(const scalar x) const
template<class Type>
Type Foam::PolynomialEntry<Type>::value(const scalar x) const
{
scalar y = 0.0;
Type y(pTraits<Type>::zero);
forAll(coeffs_, i)
{
y += coeffs_[i].first()*pow(x, coeffs_[i].second());
y += cmptMultiply
(
coeffs_[i].first(),
cmptPow(pTraits<Type>::one*x, coeffs_[i].second())
);
}
return y;
}
Foam::scalar Foam::polynomial::integrate(const scalar x1, const scalar x2) const
template<class Type>
Type Foam::PolynomialEntry<Type>::integrate
(
const scalar x1,
const scalar x2
) const
{
scalar intx = 0.0;
Type intx(pTraits<Type>::zero);
if (canIntegrate_)
{
forAll(coeffs_, i)
{
intx +=
coeffs_[i].first()/(coeffs_[i].second() + 1)
*(
pow(x2, coeffs_[i].second() + 1)
- pow(x1, coeffs_[i].second() + 1)
);
intx += cmptMultiply
(
cmptDivide
(
coeffs_[i].first(),
coeffs_[i].second() + pTraits<Type>::one
),
cmptPow
(
pTraits<Type>::one*x2,
coeffs_[i].second() + pTraits<Type>::one
)
- cmptPow
(
pTraits<Type>::one*x1,
coeffs_[i].second() + pTraits<Type>::one
)
);
}
}
......@@ -194,22 +220,24 @@ Foam::scalar Foam::polynomial::integrate(const scalar x1, const scalar x2) const
}
Foam::dimensioned<Foam::scalar> Foam::polynomial::dimValue
template<class Type>
Foam::dimensioned<Type> Foam::PolynomialEntry<Type>::dimValue
(
const scalar x
) const
{
return dimensioned<scalar>("dimensionedValue", dimensions_, value(x));
return dimensioned<Type>("dimensionedValue", dimensions_, value(x));
}
Foam::dimensioned<Foam::scalar> Foam::polynomial::dimIntegrate
template<class Type>
Foam::dimensioned<Type> Foam::PolynomialEntry<Type>::dimIntegrate
(
const scalar x1,
const scalar x2
) const
{
return dimensioned<scalar>
return dimensioned<Type>
(
"dimensionedValue",
dimensions_,
......@@ -218,4 +246,9 @@ Foam::dimensioned<Foam::scalar> Foam::polynomial::dimIntegrate
}
// * * * * * * * * * * * * * * IOStream operators * * * * * * * * * * * * * //
#include "PolynomialEntryIO.C"
// ************************************************************************* //
......@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
......@@ -22,15 +22,15 @@ License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::polynomial
Foam::PolynomialEntry
Description
Polynomial container data entry for scalars. Items are stored in a list of
Tuple2's. Data is input in the form, e.g. for an entry \<entryName\> that
describes y = x^2 + 2x^3
PolynomialEntry container data entry for scalars. Items are stored in a
list of Tuple2's. Data is input in the form,
e.g. for an entry \<entryName\> that describes y = x^2 + 2x^3
\verbatim
<entryName> polynomial [0 0 1 0 0] // optional dimensions
<entryName> polynomial [0 0 1 0 0] // optional dimensions
(
(1 2)
(2 3)
......@@ -38,12 +38,12 @@ Description
\endverbatim
SourceFiles
polynomial.C
PolynomialEntry.C
\*---------------------------------------------------------------------------*/
#ifndef polynomial_H
#define polynomial_H
#ifndef PolynomialEntry_H
#define PolynomialEntry_H
#include "DataEntry.H"
#include "Tuple2.H"
......@@ -56,27 +56,27 @@ namespace Foam
{
// Forward declaration of classes
class polynomial;
template<class Type>
class PolynomialEntry;
// Forward declaration of friend functions
Ostream& operator<<
(
Ostream&,
const polynomial&
);
template<class Type>
Ostream& operator<<(Ostream&, const PolynomialEntry<Type>&);
/*---------------------------------------------------------------------------*\
Class polynomial Declaration
Class PolynomialEntry Declaration
\*---------------------------------------------------------------------------*/
class polynomial
template<class Type>
class PolynomialEntry
:
public scalarDataEntry
public DataEntry<Type>
{
// Private data
//- Polynomial coefficients - list of prefactor, exponent
List<Tuple2<scalar, scalar> > coeffs_;
//- PolynomialEntry coefficients - list of prefactor, exponent
List<Tuple2<Type, Type> > coeffs_;
//- Flag to indicate whether poly can be integrated
bool canIntegrate_;
......@@ -88,7 +88,7 @@ class polynomial
// Private Member Functions
//- Disallow default bitwise assignment
void operator=(const polynomial&);
void operator=(const PolynomialEntry<Type>&);
public:
......@@ -99,23 +99,27 @@ public:
// Constructors
polynomial(const word& entryName, const dictionary& dict);
PolynomialEntry(const word& entryName, const dictionary& dict);
//- Construct from components
polynomial(const word& entryName, const List<Tuple2<scalar, scalar> >&);
PolynomialEntry
(
const word& entryName,
const List<Tuple2<Type, Type> >&
);
//- Copy constructor
polynomial(const polynomial& poly);
PolynomialEntry(const PolynomialEntry& poly);
//- Construct and return a clone
virtual tmp<scalarDataEntry> clone() const
virtual tmp<DataEntry<Type> > clone() const
{
return tmp<scalarDataEntry>(new polynomial(*this));
return tmp<DataEntry<Type> >(new PolynomialEntry(*this));
}
//- Destructor
virtual ~polynomial();
virtual ~PolynomialEntry();
// Member Functions
......@@ -128,17 +132,17 @@ public:
// Evaluation
//- Return polynomial value
scalar value(const scalar x) const;
//- Return PolynomialEntry value
Type value(const scalar x) const;
//- Integrate between two (scalar) values
scalar integrate(const scalar x1, const scalar x2) const;
Type integrate(const scalar x1, const scalar x2) const;
//- Return dimensioned constant value
dimensioned<scalar> dimValue(const scalar) const;
dimensioned<Type> dimValue(const scalar) const;
//- Integrate between two values and return dimensioned type
dimensioned<scalar> dimIntegrate
dimensioned<Type> dimIntegrate
(
const scalar x1,
const scalar x2
......@@ -148,10 +152,10 @@ public:
// I/O
//- Ostream Operator
friend Ostream& operator<<
friend Ostream& operator<< <Type>
(
Ostream& os,
const polynomial& cnst
const PolynomialEntry<Type>& cnst
);
//- Write in dictionary format
......@@ -165,6 +169,12 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "PolynomialEntry.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //
......@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
......@@ -23,24 +23,25 @@ License
\*---------------------------------------------------------------------------*/
#include "polynomial.H"
#include "PolynomialEntry.H"
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
template<class Type>
Foam::Ostream& Foam::operator<<
(
Ostream& os,
const polynomial& poly
const PolynomialEntry<Type>& poly
)
{
if (os.format() == IOstream::ASCII)
{
os << static_cast<const DataEntry<scalar>& >(poly)
os << static_cast<const DataEntry<Type>& >(poly)
<< token::SPACE << poly.coeffs_;
}
else
{
os << static_cast<const DataEntry<scalar>& >(poly);
os << static_cast<const DataEntry<Type>& >(poly);
os.write
(
reinterpret_cast<const char*>(&poly.coeffs_),
......@@ -51,16 +52,17 @@ Foam::Ostream& Foam::operator<<
// Check state of Ostream
os.check
(