Polynomial.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2015 OpenFOAM Foundation
9  Copyright (C) 2020 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "Polynomial.H"
30 
31 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
32 
33 template<int PolySize>
35 :
36  VectorSpace<Polynomial<PolySize>, scalar, PolySize>(Zero),
37  logActive_(false),
38  logCoeff_(0)
39 {}
40 
41 
42 template<int PolySize>
43 Foam::Polynomial<PolySize>::Polynomial(std::initializer_list<scalar> coeffs)
44 :
45  VectorSpace<Polynomial<PolySize>, scalar, PolySize>(),
46  logActive_(false),
47  logCoeff_(0)
48 {
49  if (coeffs.size() != PolySize)
50  {
52  << "Size mismatch: Needed " << PolySize
53  << " but given " << label(coeffs.size())
54  << nl << exit(FatalError);
55  }
56 
57  auto iter = coeffs.begin();
58  for (int i=0; i<PolySize; ++i)
59  {
60  this->v_[i] = *iter;
61  ++iter;
62  }
63 }
64 
65 
66 template<int PolySize>
67 Foam::Polynomial<PolySize>::Polynomial(const scalar coeffs[PolySize])
68 :
69  VectorSpace<Polynomial<PolySize>, scalar, PolySize>(),
70  logActive_(false),
71  logCoeff_(0)
72 {
73  for (int i=0; i<PolySize; ++i)
74  {
75  this->v_[i] = coeffs[i];
76  }
77 }
78 
79 
80 template<int PolySize>
82 :
83  VectorSpace<Polynomial<PolySize>, scalar, PolySize>(),
84  logActive_(false),
85  logCoeff_(0)
86 {
87  if (coeffs.size() != PolySize)
88  {
90  << "Size mismatch: Needed " << PolySize
91  << " but given " << coeffs.size()
92  << nl << exit(FatalError);
93  }
94 
95  for (int i = 0; i < PolySize; ++i)
96  {
97  this->v_[i] = coeffs[i];
98  }
99 }
100 
101 
102 template<int PolySize>
104 :
105  VectorSpace<Polynomial<PolySize>, scalar, PolySize>(is),
106  logActive_(false),
107  logCoeff_(0)
108 {}
109 
110 
111 template<int PolySize>
113 :
114  VectorSpace<Polynomial<PolySize>, scalar, PolySize>(),
115  logActive_(false),
116  logCoeff_(0)
117 {
118  const word isName(is);
119 
120  if (isName != name)
121  {
123  << "Expected polynomial name " << name << " but read " << isName
124  << nl << exit(FatalError);
125  }
126 
127  is >>
128  static_cast
129  <
130  VectorSpace<Polynomial<PolySize>, scalar, PolySize>&
131  >(*this);
132 }
133 
134 
135 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
136 
137 template<int PolySize>
139 {
140  return logActive_;
141 }
142 
143 
144 template<int PolySize>
146 {
147  return logCoeff_;
148 }
149 
150 
151 template<int PolySize>
152 Foam::scalar Foam::Polynomial<PolySize>::value(const scalar x) const
153 {
154  scalar val = this->v_[0];
155 
156  // Avoid costly pow() in calculation
157  scalar powX = x;
158  for (label i=1; i<PolySize; ++i)
159  {
160  val += this->v_[i]*powX;
161  powX *= x;
162  }
163 
164  if (logActive_)
165  {
166  val += logCoeff_*log(x);
167  }
168 
169  return val;
170 }
171 
172 
173 template<int PolySize>
174 Foam::scalar Foam::Polynomial<PolySize>::derivative(const scalar x) const
175 {
176  scalar deriv = 0;
177 
178  if (PolySize > 1)
179  {
180  // Avoid costly pow() in calculation
181  deriv += this->v_[1];
182 
183  scalar powX = x;
184  for (label i=2; i<PolySize; ++i)
185  {
186  deriv += i*this->v_[i]*powX;
187  powX *= x;
188  }
189  }
190 
191  if (logActive_)
192  {
193  deriv += logCoeff_/x;
194  }
195 
196  return deriv;
197 }
198 
199 
200 template<int PolySize>
202 (
203  const scalar x1,
204  const scalar x2
205 ) const
206 {
207  // Avoid costly pow() in calculation
208  scalar powX1 = x1;
209  scalar powX2 = x2;
210 
211  scalar integ = this->v_[0]*(powX2 - powX1);
212  for (label i=1; i<PolySize; ++i)
213  {
214  powX1 *= x1;
215  powX2 *= x2;
216  integ += this->v_[i]/(i + 1)*(powX2 - powX1);
217  }
218 
219  if (logActive_)
220  {
221  integ += logCoeff_*((x2*log(x2) - x2) - (x1*log(x1) - x1));
222  }
223 
224  return integ;
225 }
226 
227 
228 template<int PolySize>
230 Foam::Polynomial<PolySize>::integral(const scalar intConstant) const
231 {
232  intPolyType newCoeffs;
233 
234  newCoeffs[0] = intConstant;
235  forAll(*this, i)
236  {
237  newCoeffs[i+1] = this->v_[i]/(i + 1);
238  }
239 
240  return newCoeffs;
241 }
242 
243 
244 template<int PolySize>
246 Foam::Polynomial<PolySize>::integralMinus1(const scalar intConstant) const
247 {
248  polyType newCoeffs;
249 
250  if (this->v_[0] > VSMALL)
251  {
252  newCoeffs.logActive_ = true;
253  newCoeffs.logCoeff_ = this->v_[0];
254  }
255 
256  newCoeffs[0] = intConstant;
257  for (label i=1; i<PolySize; ++i)
258  {
259  newCoeffs[i] = this->v_[i]/i;
260  }
261 
262  return newCoeffs;
263 }
264 
265 
266 // ************************************************************************* //
Foam::Polynomial::integralMinus1
polyType integralMinus1(const scalar intConstant=0.0) const
Return integral coefficients when lowest order is -1.
Definition: Polynomial.C:246
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:65
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
Foam::Polynomial::derivative
scalar derivative(const scalar x) const
Return derivative of the polynomial at the given x.
Definition: Polynomial.C:174
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::VectorSpace
Templated vector space.
Definition: VectorSpace.H:56
Foam::Polynomial::integral
scalar integral(const scalar x1, const scalar x2) const
Return integral between two values.
Definition: Polynomial.C:202
Foam::Polynomial::Polynomial
Polynomial()
Default construct, with all coefficients = 0.
Definition: Polynomial.C:34
Foam::Istream
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:61
Foam::Polynomial::logActive
bool logActive() const
Return true if the log term is active.
Definition: Polynomial.C:138
Foam::Polynomial::value
scalar value(const scalar x) const
Return polynomial value.
Definition: Polynomial.C:152
Polynomial.H
Foam::FatalError
error FatalError
Foam::log
dimensionedScalar log(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:262
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::Polynomial
Polynomial templated on size (order):
Definition: Polynomial.H:68
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::nl
constexpr char nl
Definition: Ostream.H:404
Foam::Polynomial::logCoeff
scalar logCoeff() const
Return the log coefficient.
Definition: Polynomial.C:145
Foam::UList
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: HashTable.H:103
x
x
Definition: LISASMDCalcMethod2.H:52
Foam::name
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:59
Foam::UList::size
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114