### ENH: additional polynomial constructors, improved I/O

```- support construct from initializer_list, which can help simplify
code with constant coefficients.

to support resizable lists of polynomialFunction.

A default constructed polynomialFunction is simply equivalent to
a constant zero.

- no special IO handling for Polynomial required,
it is the same as VectorSpace anyhow.```
parent 95f7ed03
 ... ... @@ -6,6 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011 OpenFOAM Foundation Copyright (C) 2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. ... ... @@ -24,24 +25,29 @@ License along with OpenFOAM. If not, see . Application PolynomialTest Test-Polynomial Description Test application for the templated Polynomial class \*---------------------------------------------------------------------------*/ #include "StringStream.H" #include "Polynomial.H" #include "FixedList.H" #include "polynomialFunction.H" #include "ITstream.H" #include "OTstream.H" #include "Random.H" #include "cpuTime.H" using namespace Foam; const int PolySize = 8; const scalar coeff[] = { 0.11, 0.45, -0.94, 1.58, -2.58, 0.08, 3.15, -4.78 }; const char* polyDef = "(0.11 0.45 -0.94 1.58 -2.58 0.08 3.15 -4.78)"; std::initializer_list coeffs { 0.11, 0.45, -0.94, 1.58, -2.58, 0.08, 3.15, -4.78 }; const FixedList coeff(coeffs); scalar polyValue(const scalar x) ... ... @@ -76,10 +82,10 @@ scalar intPolyValue(const scalar x) scalar polyValue1(const scalar x) { // "normal" evaluation using pow() // Naive evaluation using pow() scalar value = coeff; for (int i=1; i < PolySize; ++i) for (label i=1; i < coeff.size(); ++i) { value += coeff[i]*pow(x, i); } ... ... @@ -90,11 +96,11 @@ scalar polyValue1(const scalar x) scalar polyValue2(const scalar x) { // calculation avoiding pow() // Calculation avoiding pow() scalar value = coeff; scalar powX = x; for (int i=1; i < PolySize; ++i) for (label i=1; i < coeff.size(); ++i) { value += coeff[i] * powX; powX *= x; ... ... @@ -108,19 +114,27 @@ scalar polyValue2(const scalar x) int main(int argc, char *argv[]) { const label n = 10000; const label nIters = 1000; scalar sum = 0.0; constexpr label n = 10000; constexpr label nIters = 1000; scalar sum = 0; Info<< "null poly = " << (Polynomial<8>()) << nl << "null poly = " << (polynomialFunction(8)) << nl Info<< "null poly = " << (Polynomial<8>{}) << nl << "null poly = " << (polynomialFunction{8}) << nl << endl; Polynomial<8> poly(coeff); Polynomial<9> intPoly(poly.integral(0.0)); Polynomial<8> poly{coeffs}; Polynomial<9> intPoly{poly.integral(0)}; polynomialFunction polyfunc; IStringStream is(polyDef); polynomialFunction polyfunc(is); // Could profit from a bi-directional stream { OTstream os; os << poly; ITstream is("input", std::move(os.tokens())); is >> polyfunc; } Info<< "poly = " << poly << nl << "intPoly = " << intPoly << nl ... ... @@ -152,7 +166,7 @@ int main(int argc, char *argv[]) Info<< "2.5*poly = " << polyCopy << nl << endl; Random rnd(123456); for (int i=0; i<10; i++) for (label i=0; i<10; ++i) { scalar x = rnd.sample01()*100; ... ... @@ -162,18 +176,18 @@ int main(int argc, char *argv[]) scalar pxTest = poly.value(x); scalar ipxTest = intPoly.value(x); Info<<"\nx = " << x << endl; Info<< " px, pxTest = " << px << ", " << pxTest << endl; Info<< " ipx, ipxTest = " << ipx << ", " << ipxTest << endl; Info<<"\nx = " << x << nl << " px, pxTest = " << px << ", " << pxTest << nl << " ipx, ipxTest = " << ipx << ", " << ipxTest << nl; if (mag(px - pxTest) > SMALL) { Info<< " *** WARNING: px != pxTest: " << px - pxTest << endl; Info<< " *** WARNING: px != pxTest: " << px - pxTest << nl; } if (mag(ipx - ipxTest) > SMALL) { Info<< " *** WARNING: ipx != ipxTest: " << ipx - ipxTest << endl; Info<< " *** WARNING: ipx != ipxTest: " << ipx - ipxTest << nl; } Info<< endl; ... ... @@ -188,7 +202,7 @@ int main(int argc, char *argv[]) cpuTime timer; for (int loop = 0; loop < n; ++loop) for (label loop = 0; loop < n; ++loop) { sum = 0.0; for (label iter = 0; iter < nIters; ++iter) ... ... @@ -199,7 +213,7 @@ int main(int argc, char *argv[]) Info<< "value: " << sum << " in " << timer.cpuTimeIncrement() << " s\n"; for (int loop = 0; loop < n; ++loop) for (label loop = 0; loop < n; ++loop) { sum = 0.0; for (label iter = 0; iter < nIters; ++iter) ... ... @@ -211,7 +225,7 @@ int main(int argc, char *argv[]) << " in " << timer.cpuTimeIncrement() << " s\n"; for (int loop = 0; loop < n; ++loop) for (label loop = 0; loop < n; ++loop) { sum = 0.0; for (label iter = 0; iter < nIters; ++iter) ... ... @@ -223,7 +237,7 @@ int main(int argc, char *argv[]) << " in " << timer.cpuTimeIncrement() << " s\n"; for (int loop = 0; loop < n; ++loop) for (label loop = 0; loop < n; ++loop) { sum = 0.0; for (label iter = 0; iter < nIters; ++iter) ... ... @@ -234,7 +248,7 @@ int main(int argc, char *argv[]) Info<< "hard-coded 1: " << sum << " in " << timer.cpuTimeIncrement() << " s\n"; for (int loop = 0; loop < n; ++loop) for (label loop = 0; loop < n; ++loop) { sum = 0.0; for (label iter = 0; iter < nIters; ++iter) ... ...
 ... ... @@ -6,6 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2015 OpenFOAM Foundation Copyright (C) 2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. ... ... @@ -31,14 +32,33 @@ License template Foam::Polynomial::Polynomial() : VectorSpace, scalar, PolySize>(Zero), logActive_(false), logCoeff_(0) {} template Foam::Polynomial::Polynomial(std::initializer_list coeffs) : VectorSpace, scalar, PolySize>(), logActive_(false), logCoeff_(0) { for (int i = 0; i < PolySize; ++i) if (coeffs.size() != PolySize) { this->v_[i] = 0; FatalErrorInFunction << "Size mismatch: Needed " << PolySize << " but given " << label(coeffs.size()) << nl << exit(FatalError); } auto iter = coeffs.begin(); for (int i=0; iv_[i] = *iter; ++iter; } } ... ... @@ -50,7 +70,7 @@ Foam::Polynomial::Polynomial(const scalar coeffs[PolySize]) logActive_(false), logCoeff_(0) { for (int i=0; iv_[i] = coeffs[i]; } ... ... @@ -95,7 +115,7 @@ Foam::Polynomial::Polynomial(const word& name, Istream& is) logActive_(false), logCoeff_(0) { word isName(is); const word isName(is); if (isName != name) { ... ... @@ -104,15 +124,11 @@ Foam::Polynomial::Polynomial(const word& name, Istream& is) << nl << exit(FatalError); } VectorSpace, scalar, PolySize>:: operator=(VectorSpace, scalar, PolySize>(is)); if (this->size() == 0) { FatalErrorInFunction << "Polynomial coefficients for entry " << isName << " are invalid (empty)" << nl << exit(FatalError); } is >> static_cast < VectorSpace, scalar, PolySize>& >(*this); } ... ... @@ -137,12 +153,12 @@ Foam::scalar Foam::Polynomial::value(const scalar x) const { scalar val = this->v_; // avoid costly pow() in calculation scalar powX = 1; // Avoid costly pow() in calculation scalar powX = x; for (label i=1; iv_[i]*powX; powX *= x; } if (logActive_) ... ... @@ -161,14 +177,14 @@ Foam::scalar Foam::Polynomial::derivative(const scalar x) const if (PolySize > 1) { // avoid costly pow() in calculation // Avoid costly pow() in calculation deriv += this->v_; scalar powX = 1; scalar powX = x; for (label i=2; iv_[i]*powX; powX *= x; } } ... ... @@ -188,7 +204,7 @@ Foam::scalar Foam::Polynomial::integral const scalar x2 ) const { // avoid costly pow() in calculation // Avoid costly pow() in calculation scalar powX1 = x1; scalar powX2 = x2; ... ...
 ... ... @@ -57,6 +57,7 @@ SourceFiles #include "scalar.H" #include "Ostream.H" #include "VectorSpace.H" #include #include // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ... ... @@ -67,9 +68,6 @@ namespace Foam // Forward Declarations template class Polynomial; template Ostream& operator<<( Ostream&, const Polynomial&); /*---------------------------------------------------------------------------*\ Class Polynomial Declaration \*---------------------------------------------------------------------------*/ ... ... @@ -106,6 +104,9 @@ public: //- Default construct, with all coefficients = 0 Polynomial(); //- Construct from an initializer list of coefficients Polynomial(std::initializer_list coeffs); //- Construct from C-array of coefficients explicit Polynomial(const scalar coeffs[PolySize]); ... ... @@ -150,12 +151,7 @@ public: polyType integralMinus1(const scalar intConstant = 0.0) const; //- Ostream Operator friend Ostream& operator<< ( Ostream&, const Polynomial& ); // IOstream Operators - uses VectorSpace operators }; ... ... @@ -167,7 +163,6 @@ public: #ifdef NoRepository #include "Polynomial.C" #include "PolynomialIO.C" #endif // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ... ...