multiDimPolyFitter.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) 2019-2020 DLR
9-------------------------------------------------------------------------------
10License
11 This file is part of OpenFOAM.
12
13 OpenFOAM is free software: you can redistribute it and/or modify it
14 under the terms of the GNU General Public License as published by
15 the Free Software Foundation, either version 3 of the License, or
16 (at your option) any later version.
17
18 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25
26\*---------------------------------------------------------------------------*/
27
28#include "multiDimPolyFitter.H"
29
30// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
31
32template<class T>
34(
35 const word& polyFunctionName,
36 const labelVector& geomDirs
37)
38:
39 polyFunc_(multiDimPolyFunctions::New(polyFunctionName,geomDirs)),
40 A_(polyFunc_->nTerms(), scalar(0), Zero)
41{}
42
43
44// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
45
46template<class T>
48{
49 for (label i=0;i<A_.size();i++)
50 {
51 A_.data()[i] = Zero;
52 }
53 A_.source() = Zero;
54}
55
56
57template<class T>
59(
60 const scalarField& polyTerms,
61 const T& value
62)
63{
64 const label size = A_.n();
65
66 // simple matrix is a square
67
68 for (label i=0; i<size; ++i) // col
69 {
70 A_.source()[i] += polyTerms[i]*value;
71 scalar* luMatrixi = A_[i];
72 const scalar tmpValue = polyTerms[i];
73
74 for (label j=0; j<size; ++j) // row
75 {
76 luMatrixi[j] += tmpValue*polyTerms[j];
77 }
78 }
79}
80
81
82template<class T>
84(
85 const scalarField& polyTerms,
86 const T& value,
87 const scalar weight
88)
89{
90 const label size = A_.n();
91
92 //simple matrix is a square
93
94 for (label i=0; i<size; ++i) // col
95 {
96 A_.source()[i] += polyTerms[i]*value*weight;
97 scalar* __restrict luMatrixi = A_[i];
98 const scalar tmpValue = polyTerms[i];
99
100 for (label j=0; j<size; j++) // row
101 {
102 luMatrixi[j] += tmpValue*polyTerms[j]*weight;
103 }
104 }
105}
106
107
108template<class T>
110(
111 const scalarField& polyTerms,
113)
114{
115 const label size = A.n();
116
117 // simple matrix is a square
118 for (label i=0; i<size; ++i)
119 {
120 for (label j=0; j<size; ++j)
121 {
122 A[i][j] += polyTerms[i]*polyTerms[j];
123 }
124 }
125}
126
127
128template<class T>
130(
131 const List<scalarField>& listPolyTerms,
132 const List<T>& listValue
133)
134{
135 // operator= does not work
136 resetMatrix();
137 if (listPolyTerms.size() == listValue.size())
138 {
139 forAll(listPolyTerms,i)
140 {
141 fillMatrix
142 (
143 listPolyTerms[i],
144 listValue[i]
145 );
146 }
147 // Solve the matrix using Gaussian elimination with pivoting
148 return A_.LUsolve();
149 }
150 else
151 {
153 << "size of listPolyTerms: " << listPolyTerms.size()
154 << "size of listValues is: " << listValue.size()
155 << " they must match!" << nl
156 << exit(FatalError);
157 return Field<T>();
158 }
159}
160
161
162template<class T>
164(
165 const List<scalarField>& listPolyTerms,
166 const List<T>& listValue,
167 const List<scalar>& listWeight
168)
169{
170 // operator= does not work
171 resetMatrix();
172 if (listPolyTerms.size() == listValue.size())
173 {
174 forAll(listPolyTerms, i)
175 {
176 fillMatrix
177 (
178 listPolyTerms[i],
179 listValue[i],
180 listWeight[i]
181 );
182 }
183
184 // Solve the matrix using Gaussian elimination with pivoting
185 return A_.LUsolve();
186 }
187 else
188 {
190 << "size of listPolyTerms: " << listPolyTerms.size()
191 << "size of listValues is:" << listValue.size()
192 << "they have to match"
193 << exit(FatalError);
194
195 return Field<T>();
196 }
197}
198
199
200template<class T>
202(
203 const List<scalarField>& listPolyTerms
204)
205{
206 // operator= does not work
207 scalarSymmetricSquareMatrix symMatrix(A_.n(), Zero);
208 forAll(listPolyTerms,i)
209 {
210 fillMatrix
211 (
212 listPolyTerms[i],
213 symMatrix
214 );
215 }
216
217 return inv(symMatrix);
218}
219
220
221template<class T>
223(
224 const List<scalarField>& listPolyTerms,
225 const List<T>& listValue
226)
227{
228 if (listPolyTerms.size() != listValue.size())
229 {
231 << "size of listPolyTerms: " << listPolyTerms.size()
232 << "size of listValues is:" << listValue.size()
233 << "they have to match"
234 << exit(FatalError);
235 }
236
237 Field<T> source(listPolyTerms.size(), Zero);
238
239 forAll(source, i)
240 {
241 forAll(listPolyTerms[i], j)
242 {
243 source[i] += listPolyTerms[i][j]*listValue[i];
244 }
245 }
246
247 return source;
248}
249
250
251template<class T>
253(
254 const List<vector>& positions,
255 const List<T>& listValue
256)
257{
258 // operator= does not work
259 if (positions.size() != listValue.size())
260 {
262 << "size of positions and listValues don't match" << nl
263 << "size of positions is: " << positions.size() << nl
264 << "size of listValues is: " << listValue.size() << nl
265 << exit(FatalError);
266 }
267
268 resetMatrix();
269
270 forAll(positions, i)
271 {
272 fillMatrix
273 (
274 polyFunc_->termValues(positions[i]),
275 listValue[i]
276 );
277 }
278
279 // Solve the matrix using Gaussian elimination with pivoting
280 return A_.LUsolve();
281}
282
283
284template<class T>
286(
287 const List<vector>& positions,
288 const List<T>& listValue,
289 const List<scalar>& listWeight
290)
291{
292 // operator= does not work
293 if (positions.size() != listValue.size())
294 {
296 << "size of positions and listValues don't match" << nl
297 << "size of positions is: " << positions.size() << nl
298 << "size of listValues is: " << listValue.size() << nl
299 << exit(FatalError);
300 }
301
302 resetMatrix();
303
304 forAll(positions, i)
305 {
306 fillMatrix
307 (
308 polyFunc_->termValues(positions[i]),
309 listValue[i],
310 listWeight[i]
311 );
312 }
313
314 // Solve the matrix using Gaussian elimination with pivoting
315 return A_.LUsolve();
316}
317
318
319template<class T>
321(
322 const List<vector>& positions
323)
324{
325 // operator= does not work
326 scalarSymmetricSquareMatrix symMatrix(A_.n(), Zero);
327 forAll(positions, i)
328 {
329 fillMatrix
330 (
331 polyFunc_->termValues(positions[i]),
332 symMatrix
333 );
334 }
335
336 return inv(symMatrix);
337}
338
339
340template<class T>
342(
343 const List<vector>& positions,
344 const List<T>& listValue
345)
346{
347 if (positions.size() != listValue.size())
348 {
350 << "size of positions: " << positions.size()
351 << "size of listValues is:" << listValue.size()
352 << "they have to match"
353 << exit(FatalError);
354 }
355
356 Field<T> source(polyFunc_->nTerms(), Zero);
357
358 forAll(source, i)
359 {
360 scalarField polyTerms = polyFunc_->termValues(positions[i]);
361 forAll(polyTerms, j)
362 {
363 source[i] += polyTerms[j]*listValue[i];
364 }
365 }
366
367 return source;
368}
369
370
373
374
375// ************************************************************************* //
static const Foam::dimensionedScalar A("", Foam::dimPressure, 611.21)
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: List.H:77
A templated (N x N) square matrix of objects of <Type>, containing N*N elements, derived from Matrix.
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
Fit a polynominal function with the help of multiDimPolyFunction.
Field< T > computeMatrixSource(const List< scalarField > &listPolyTerms, const List< T > &listValue)
Compute source.
void fillMatrix(const scalarField &polyTerms, const T &value)
scalarSymmetricSquareMatrix computeInverse(const List< scalarField > &listPolyTerms)
Compute inverse.
Field< T > fitData(const List< scalarField > &listPolyTerms, const List< T > &listValue)
Fit data.
base class for polynomial functions
A class for handling words, derived from Foam::string.
Definition: word.H:68
const volScalarField & T
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh > > &tdf1, const word &name, const dimensionSet &dimensions)
Global function forwards to reuseTmpDimensionedField::New.
error FatalError
dimensionedSphericalTensor inv(const dimensionedSphericalTensor &dt)
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333