Loading...
Searching...
No Matches
ITHACAfieldsOperations.C
Go to the documentation of this file.
1/*---------------------------------------------------------------------------*\
2 ██╗████████╗██╗ ██╗ █████╗ ██████╗ █████╗ ███████╗██╗ ██╗
3 ██║╚══██╔══╝██║ ██║██╔══██╗██╔════╝██╔══██╗ ██╔════╝██║ ██║
4 ██║ ██║ ███████║███████║██║ ███████║█████╗█████╗ ██║ ██║
5 ██║ ██║ ██╔══██║██╔══██║██║ ██╔══██║╚════╝██╔══╝ ╚██╗ ██╔╝
6 ██║ ██║ ██║ ██║██║ ██║╚██████╗██║ ██║ ██║ ╚████╔╝
7 ╚═╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝ ╚═╝ ╚═══╝
8
9 * In real Time Highly Advanced Computational Applications for Finite Volumes
10 * Copyright (C) 2017 by the ITHACA-FV authors
11-------------------------------------------------------------------------------
12
13License
14 This file is part of ITHACA-FV
15
16 ITHACA-FV is free software: you can redistribute it and/or modify
17 it under the terms of the GNU Lesser General Public License as published by
18 the Free Software Foundation, either version 3 of the License, or
19 (at your option) any later version.
20
21 ITHACA-FV is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 GNU Lesser General Public License for more details.
25
26 You should have received a copy of the GNU Lesser General Public License
27 along with ITHACA-FV. If not, see <http://www.gnu.org/licenses/>.
28\*---------------------------------------------------------------------------*/
29
31
34
35// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
36
37namespace ITHACAutilities
38{
39
40template<typename T>
41void multField(T& f1, double alpha)
42{
43 int NBC = f1.boundaryField().size();
44 Eigen::VectorXd f1v = Foam2Eigen::field2Eigen(f1);
45 List<Eigen::VectorXd> f1BC = Foam2Eigen::field2EigenBC(f1);
46 for (label k = 0; k < f1v.size(); k++)
47 {
48 f1v(k) *= alpha;
49 }
50 for (label l = 0; l < NBC; l++)
51 {
52 for (label k = 0; k < f1BC[l].size(); k++)
53 {
54 f1BC[l](k) *= alpha;
55 }
56 }
57
58 f1 = Foam2Eigen::Eigen2field(f1, f1v);
59 for (int k = 0; k < f1BC.size(); k++)
60 {
61 assignBC(f1, k, f1BC[k]);
62 }
63}
64template void multField(volScalarField& f1, double alpha);
65template void multField(volVectorField& f1, double alpha);
66template void multField(volTensorField& f1, double alpha);
67
68template<typename T>
69void multField(T &f1, const Eigen::VectorXd alphaVec)
70{
71 Eigen::VectorXd f1v = Foam2Eigen::field2Eigen(f1);
72 List<Eigen::VectorXd> f1BC = Foam2Eigen::field2EigenBC(f1);
73 for (label k = 0; k < f1v.size(); k++)
74 {
75 f1v(k) *= (alphaVec[k]);
76 }
77 f1 = Foam2Eigen::Eigen2field(f1, f1v);
78 for (int k = 0; k < f1BC.size(); k++)
79 {
80 assignBC(f1, k, f1BC[k]);
81 }
82}
83template void multField(volScalarField& f1, const Eigen::VectorXd alphaVec);
84template void multField(volVectorField& f1, const Eigen::VectorXd alphaVec);
85template void multField(volTensorField& f1, const Eigen::VectorXd alphaVec);
86
87template<typename T>
88void multField(PtrList<T> &f1, const Eigen::VectorXd alphaVec)
89{
90 for(label ith_field = 0 ; ith_field < f1.size() ; ith_field++){
91 Eigen::VectorXd f1v = Foam2Eigen::field2Eigen(f1[ith_field]);
92 List<Eigen::VectorXd> f1BC = Foam2Eigen::field2EigenBC(f1[ith_field]);
93 for (label k = 0; k < f1v.size(); k++)
94 {
95 f1v(k) *= (alphaVec[k]);
96 }
97 f1[ith_field] = Foam2Eigen::Eigen2field(f1[ith_field], f1v);
98 for (int k = 0; k < f1BC.size(); k++)
99 {
100 assignBC(f1[ith_field], k, f1BC[k]);
101 }
102 }
103}
104template void multField(PtrList<volScalarField>& f1, const Eigen::VectorXd alphaVec);
105template void multField(PtrList<volVectorField>& f1, const Eigen::VectorXd alphaVec);
106template void multField(PtrList<volTensorField>& f1, const Eigen::VectorXd alphaVec);
107
108
109template<typename T>
110void addFields(T& f1, const T& f2c, double alpha)
111{
112 T f2 = f2c;
113 int NBC = f1.boundaryField().size();
114 Eigen::VectorXd f1v = Foam2Eigen::field2Eigen(f1);
115 List<Eigen::VectorXd> f1BC = Foam2Eigen::field2EigenBC(f1);
116 Eigen::VectorXd f2v = Foam2Eigen::field2Eigen(f2);
117 List<Eigen::VectorXd> f2BC = Foam2Eigen::field2EigenBC(f2);
118
119 for (label k = 0; k < f1v.size(); k++)
120 {
121 f1v(k) += alpha * f2v(k);
122 }
123 for (label l = 0; l < NBC; l++)
124 {
125 for (label k = 0; k < f1BC[l].size(); k++)
126 {
127 f1BC[l](k) += alpha * f2BC[l](k);
128 }
129 }
130
131 f1 = Foam2Eigen::Eigen2field(f1, f1v);
132 for (int k = 0; k < f1BC.size(); k++)
133 {
134 assignBC(f1, k, f1BC[k]);
135 }
136}
137template void addFields(volScalarField& f1, const volScalarField& f2c, double alpha);
138template void addFields(volVectorField& f1, const volVectorField& f2c, double alpha);
139template void addFields(volTensorField& f1, const volTensorField& f2c, double alpha);
140
141
142template<typename T>
143void subtractFields(T& f1, const T& f2)
144{
145 addFields(f1, f2, -1.0);
146}
147template void subtractFields(volScalarField& f1, const volScalarField& f2);
148template void subtractFields(volVectorField& f1, const volVectorField& f2);
149template void subtractFields(volTensorField& f1, const volTensorField& f2);
150
151
152volTensorField tensorFieldProduct(const volScalarField& coef, const volTensorField& S)
153{
154 return (coef * S);
155}
156
157volTensorField tensorFieldProduct(const volTensorField& coef, const volTensorField& S)
158{
159 return (coef & S);
160}
161
162
163int dimensionField(const volTensorField& v)
164{
165 int d = 9;
166 return d;
167}
168
169int dimensionField(const volVectorField& v)
170{
171 int d = 3;
172 return d;
173}
174
175int dimensionField(const volScalarField& v)
176{
177 int d = 1;
178 return d;
179}
180
181
182template<class TypeField>
183PtrList<TypeField> averageSubtract(PtrList<TypeField>
184 fields, Eigen::MatrixXd ind, PtrList<TypeField>& ave)
185{
186 PtrList<TypeField> aveSubtracted;
187 Eigen::VectorXd newInd;
188 newInd.resize(ind.size() + 1);
189 newInd.head(ind.size()) = ind;
190 newInd(ind.size()) = fields.size();
191
192 for (label i = 0; i < ind.size(); i++)
193 {
194 TypeField aveTemp("nut", fields[0] * 0);
195
196 for (label j = newInd(i); j < newInd(i + 1); j++)
197 {
198 aveTemp += fields[j];
199 }
200
201 aveTemp /= newInd(i + 1) - newInd(i);
202 ave.append(aveTemp.clone());
203 }
204
205 for (label i = 0; i < ind.size(); i++)
206 {
207 for (label j = newInd(i); j < newInd(i + 1); j++)
208 {
209 TypeField newfield("nut", fields[0] * 0);
210 newfield = fields[j] - ave[i];
211 aveSubtracted.append(newfield.clone());
212 }
213 }
214
215 return aveSubtracted;
216}
217
218template PtrList<volScalarField> averageSubtract(
219 PtrList<volScalarField>
220 fields, Eigen::MatrixXd ind, PtrList<volScalarField>& ave);
221template PtrList<volVectorField> averageSubtract(
222 PtrList<volVectorField>
223 fields, Eigen::MatrixXd ind, PtrList<volVectorField>& ave);
224
225
226template<class TypeField>
227TypeField computeAverage(PtrList<TypeField>& fields)
228{
229 TypeField av(fields[0]);
230
231 for (label i = 1; i < fields.size(); i++)
232 {
233 av += fields[i];
234 }
235
236 av = av / fields.size();
237 return av;
238}
239
240template volVectorField computeAverage(
241 PtrList<volVectorField>& fields);
242template volScalarField computeAverage(
243 PtrList<volScalarField>& fields);
244
245
246template<typename Type>
248 PtrList<GeometricField<Type, fvPatchField, volMesh >>& fields)
249{
251 word normType = para->ITHACAdict->lookupOrDefault<word>("normalizationNorm",
252 "L2");
253 M_Assert(normType == "L2" ||
254 normType == "Frobenius", "The normalizationNorm can be only L2 or Frobenius" );
255 Eigen::MatrixXd eigenFields = Foam2Eigen::PtrList2Eigen(fields);
256 List<Eigen::MatrixXd> eigenFieldsBC = Foam2Eigen::PtrList2EigenBC(fields);
257
258 for (label i = 0; i < fields.size(); i++)
259 {
260 double norm;
261
262 if (normType == "L2")
263 {
264 norm = L2Norm(fields[i]);
265 }
266 else if (normType == "Frobenius")
267 {
268 norm = frobNorm(fields[i]);
269 }
270
271 GeometricField<Type, fvPatchField, volMesh> tmp2(fields[0].name(),
272 fields[0] * 0);
273 Eigen::VectorXd vec = eigenFields.col(i) / norm;
274 tmp2 = Foam2Eigen::Eigen2field(tmp2, vec);
275
276 // Adjusting boundary conditions
277 for (label k = 0; k < tmp2.boundaryField().size(); k++)
278 {
279 Eigen::MatrixXd vec = eigenFieldsBC[k].col(i) / norm;
280 assignBC(tmp2, k, vec);
281 }
282
283 fields.set(i, tmp2.clone());
284 }
285}
286
287template void normalizeFields(
288 PtrList<GeometricField<scalar, fvPatchField, volMesh >>& fields);
289template void normalizeFields(
290 PtrList<GeometricField<vector, fvPatchField, volMesh >>& fields);
291
292
293template<typename Type>
294Eigen::MatrixXd getValues(GeometricField<Type, fvPatchField,
295 volMesh>& field, labelList& indices)
296{
297 List<Type> list(indices.size());
298 M_Assert(max(indices) < field.size(),
299 "The list indices are too large respect to field dimension");
300
301 for (label i = 0; i < indices.size(); i++)
302 {
303 list[i] = field[indices[i]];
304 }
305
306 return Foam2Eigen::field2Eigen(list);
307}
308
309template<>
310Eigen::MatrixXd getValues(GeometricField<vector, fvPatchField,
311 volMesh>& field, labelList& indices, labelList* xyz)
312{
313 M_Assert(max(indices) < field.size(),
314 "The list of indices is too large respect to field dimension. There is at least one value larger than the dimension of the list");
315
316 if (xyz != NULL)
317 {
318 List<scalar> list;
319 list.resize(indices.size());
320 M_Assert(max(* xyz) <= 2,
321 "The list of xyz positions contains at list one value larger than 2");
322 labelList l = * xyz;
323
324 for (label i = 0; i < indices.size(); i++)
325 {
326 list[i] = field[indices[i]][l[i]];
327 }
328
329 return Foam2Eigen::field2Eigen(list);
330 }
331 else
332 {
333 List<vector> list;
334 list.resize(indices.size());
335
336 for (label i = 0; i < indices.size(); i++)
337 {
338 list[i] = field[indices[i]];
339 }
340
341 return Foam2Eigen::field2Eigen(list);
342 }
343}
344
345template<>
346Eigen::MatrixXd getValues(GeometricField<scalar, fvPatchField,
347 volMesh>& field, labelList& indices, labelList* xyz)
348{
349 M_Assert(max(indices) < field.size(),
350 "The list of indices is too large respect to field dimension. There is at least one value larger than the dimension of the list");
351 List<scalar> list;
352 list.resize(indices.size());
353
354 for (label i = 0; i < indices.size(); i++)
355 {
356 list[i] = field[indices[i]];
357 }
358
359 return Foam2Eigen::field2Eigen(list);
360}
361
362template<typename T>
363Eigen::MatrixXd getValues(PtrList<GeometricField<T, fvPatchField,
364 volMesh >>& fields, labelList& indices, labelList* xyz)
365{
366 Eigen::MatrixXd out;
367 Eigen::MatrixXd a = getValues(fields[0], indices, xyz);
368 out.resize(a.rows(), fields.size());
369 out.col(0) = a;
370 for (label i = 1; i < fields.size(); i++)
371 {
372 out.col(i) = getValues(fields[i], indices, xyz);
373 }
374
375 return out;
376}
377
378
379template
380Eigen::MatrixXd getValues(PtrList<GeometricField<scalar, fvPatchField,
381 volMesh >>& fields, labelList& indices, labelList* xyz);
382template
383Eigen::MatrixXd getValues(PtrList<GeometricField<vector, fvPatchField,
384 volMesh >>& fields, labelList& indices, labelList* xyz);
385
386}
Header file of the ITHACAfieldsOperations file.
static GeometricField< scalar, PatchField, GeoMesh > Eigen2field(GeometricField< scalar, PatchField, GeoMesh > &field, Eigen::VectorXd &eigen_vector, bool correctBC=true)
Convert a vector in Eigen format into an OpenFOAM scalar GeometricField.
Definition Foam2Eigen.C:533
static List< Eigen::VectorXd > field2EigenBC(GeometricField< scalar, PatchField, GeoMesh > &field)
Convert an OpenFOAM scalar field to a List of Eigen Vectors, one for each boundary.
Definition Foam2Eigen.C:253
static Eigen::MatrixXd field2Eigen(GeometricField< Type, PatchField, GeoMesh > &field)
Convert a vector OpenFOAM field into an Eigen Vector.
static List< Eigen::MatrixXd > PtrList2EigenBC(PtrList< GeometricField< scalar, PatchField, GeoMesh > > &fields, label Nfields=-1)
Convert an OpenFOAM scalar field to a List of Eigen Vectors, one for each boundary.
Definition Foam2Eigen.C:273
static Eigen::MatrixXd PtrList2Eigen(PtrList< GeometricField< Type, PatchField, GeoMesh > > &fields, label Nfields=-1)
Convert a PtrList of snapshots to Eigen matrix (only internal field).
Definition Foam2Eigen.C:665
Class for the definition of some general parameters, the parameters must be defined from the file ITH...
static ITHACAparameters * getInstance(const fvMesh &mesh, Time &localTime)
Gets an instance of ITHACAparameters, to be used if the instance is not existing.
T max(Eigen::SparseMatrix< T > &mat, label &ind_row, label &ind_col)
Find the maximum of a sparse Matrix (Useful for DEIM).
Namespace to implement some useful assign operation of OF fields.
int dimensionField(const volTensorField &v)
Return the dimension of a volTensorField.
volTensorField tensorFieldProduct(const volScalarField &coef, const volTensorField &S)
Tensor field product between a volScalarField and a volTensorField.
void multField(T &f1, double alpha)
Multiplication between a field of type vol[Scalar|Vector|Tensor]Field and a double.
TypeField computeAverage(PtrList< TypeField > &fields)
Calculates the average of a list of fields.
void normalizeFields(PtrList< GeometricField< Type, fvPatchField, volMesh > > &fields)
Normalize list of Geometric fields.
double frobNorm(GeometricField< Type, PatchField, GeoMesh > &field)
Evaluate the Frobenius norm of a field.
Definition ITHACAnorm.C:355
double L2Norm(const T v)
Compute the L2 norm of v.
Definition ITHACAnorm.C:300
void addFields(T &f1, const T &f2c, double alpha)
Perform the following operation f1 + f2 * alpha with f1 and f2 being of type vol[Scalar|Vector|Tensor...
PtrList< TypeField > averageSubtract(PtrList< TypeField > fields, Eigen::MatrixXd ind, PtrList< TypeField > &ave)
A function to compute time-averaged fields for a set of different parameter samples and also the fiel...
void assignBC(GeometricField< scalar, fvPatchField, volMesh > &s, label BC_ind, double value)
Assign uniform Boundary Condition to a volScalarField.
void subtractFields(T &f1, const T &f2)
Perform the substraction (f1 - f2) between two fields of type vol[Scalar|Vector|Tensor]Field and alph...