30template<
class Type,
template<
class>
class PatchField,
class GeoMesh>
32 PtrList<GeometricField<Type, PatchField, GeoMesh>>& modes,
33 Eigen::MatrixXd& coeff_matrix, label Nmodes)
35 PtrList<GeometricField<Type, PatchField, GeoMesh>> rec_field;
38 for (label k = 0; k < coeff_matrix.cols(); k++)
40 for (label
i = 0;
i < Nmodes;
i++)
43 rec_field.append(modes[
i]*coeff_matrix(
i, k));
47 rec_field[k] += modes[
i] * coeff_matrix(
i, k);
54template PtrList<GeometricField<scalar, fvPatchField, volMesh>>
56 PtrList<GeometricField<scalar, fvPatchField, volMesh>>& modes,
57 Eigen::MatrixXd& coeff_matrix, label Nmodes);
58template PtrList<GeometricField<vector, fvPatchField, volMesh>>
60 PtrList<GeometricField<vector, fvPatchField, volMesh>>& modes,
61 Eigen::MatrixXd& coeff_matrix, label Nmodes);
62template PtrList<GeometricField<tensor, fvPatchField, volMesh>>
64 PtrList<GeometricField<tensor, fvPatchField, volMesh>>& modes,
65 Eigen::MatrixXd& coeff_matrix, label Nmodes);
67template<
class Type,
template<
class>
class PatchField,
class GeoMesh>
69 PtrList<GeometricField<Type, PatchField, GeoMesh>>& modes, label Nmodes,
70 bool consider_volumes)
84 "The Number of requested modes is larger then the available quantity.");
86 Eigen::MatrixXd M = Eigen::MatrixXd::Zero(Msize,Msize);
94 for (
int i=0;
i<V.size();
i++)
96 M += V(
i) * F.transpose().topRows(Msize).col(
i) * F.leftCols(Msize).row(
i);
101 M = F.transpose().topRows(Msize) * V.asDiagonal() * F.leftCols(Msize);
106 M = F.transpose().topRows(Msize) * F.leftCols(Msize);
109 if (Pstream::parRun())
111 reduce(M, sumOp<Eigen::MatrixXd>());
118 PtrList<GeometricField<scalar, fvPatchField, volMesh>>& modes, label Nmodes,
119 bool consider_volumes);
122 PtrList<GeometricField<scalar, fvsPatchField, surfaceMesh>>& modes,
124 bool consider_volumes =
false);
127 PtrList<GeometricField<vector, fvPatchField, volMesh>>& modes, label Nmodes,
128 bool consider_volumes);
131 PtrList<GeometricField<tensor, fvPatchField, volMesh>>& modes, label Nmodes,
132 bool consider_volumes);
134template<
class Type,
template<
class>
class PatchField,
class GeoMesh>
136 PtrList<GeometricField<Type, PatchField, GeoMesh>>& modes,
137 PtrList<GeometricField<Type, PatchField, GeoMesh>>& modes2, label Nmodes,
138 bool consider_volumes)
143 Msize = modes.size();
144 Msize2 = modes2.size();
152 "The Number of requested modes is larger then the available quantity.");
154 "The Number of requested modes is larger then the available quantity.");
158 Eigen::MatrixXd M = Eigen::MatrixXd::Zero(Msize,Msize2);
160 if (consider_volumes)
166 for (
int i=0;
i<V.size();
i++)
168 M += V(
i) * F.transpose().topRows(Msize).col(
i) * F2.leftCols(Msize2).row(
i);
174 M = F.transpose().topRows(Msize) * V.asDiagonal() * F2.leftCols(Msize2);
179 M = F.transpose().topRows(Msize) * F2.leftCols(Msize2);
182 if (Pstream::parRun())
184 reduce(M, sumOp<Eigen::MatrixXd>());
191 PtrList<GeometricField<scalar, fvPatchField, volMesh>>& modes,
192 PtrList<GeometricField<scalar, fvPatchField, volMesh>>& modes2, label Nmodes,
193 bool consider_volumes);
196 PtrList<GeometricField<scalar, fvsPatchField, surfaceMesh>>& modes,
197 PtrList<GeometricField<scalar, fvsPatchField, surfaceMesh>>& modes2,
199 bool consider_volumes =
false);
202 PtrList<GeometricField<vector, fvPatchField, volMesh>>& modes,
203 PtrList<GeometricField<vector, fvPatchField, volMesh>>& modes2, label Nmodes,
204 bool consider_volumes);
207 PtrList<GeometricField<tensor, fvPatchField, volMesh>>& modes,
208 PtrList<GeometricField<tensor, fvPatchField, volMesh>>& modes2, label Nmodes,
209 bool consider_volumes);
212template<
class Type,
template<
class>
class PatchField,
class GeoMesh>
213Eigen::MatrixXd
getMassMatrix(PtrList<GeometricField<Type, PatchField, GeoMesh>>& modes,
214 PtrList<GeometricField<Type, PatchField, GeoMesh>>& modes2,
215 Eigen::VectorXd weights,
217 bool consider_volumes)
222 Msize = modes.size();
223 Msize2 = modes2.size();
231 "The Number of requested modes is larger then the available quantity.");
233 "The Number of requested modes is larger then the available quantity.");
237 Eigen::MatrixXd M = Eigen::MatrixXd::Zero(Msize,Msize2);
239 if (consider_volumes)
245 for (
int i=0;
i<V.size();
i++)
247 M += (V(
i) * weights(
i)) * F.transpose().topRows(Msize).col(
i) * F2.leftCols(Msize2).row(
i);
253 M = F.transpose().topRows(Msize) * ( V * weights ).asDiagonal() * F2.leftCols(Msize2);
258 M = F.transpose().topRows(Msize) * weights.asDiagonal() * F2.leftCols(Msize2);
261 if (Pstream::parRun())
263 reduce(M, sumOp<Eigen::MatrixXd>());
270 PtrList<GeometricField<scalar, fvPatchField, volMesh>>& modes,
271 PtrList<GeometricField<scalar, fvPatchField, volMesh>>& modes2,
272 Eigen::VectorXd weights,
274 bool consider_volumes);
277 PtrList<GeometricField<scalar, fvsPatchField, surfaceMesh>>& modes,
278 PtrList<GeometricField<scalar, fvsPatchField, surfaceMesh>>& modes2,
279 Eigen::VectorXd weights,
281 bool consider_volumes);
284 PtrList<GeometricField<vector, fvPatchField, volMesh>>& modes,
285 PtrList<GeometricField<vector, fvPatchField, volMesh>>& modes2,
286 Eigen::VectorXd weights,
288 bool consider_volumes);
291 PtrList<GeometricField<tensor, fvPatchField, volMesh>>& modes,
292 PtrList<GeometricField<tensor, fvPatchField, volMesh>>& modes2,
293 Eigen::VectorXd weights,
295 bool consider_volumes);
298template<
class Type,
template<
class>
class PatchField,
class GeoMesh>
300 GeometricField<Type, PatchField, GeoMesh>& snapshot)
303 label dim = std::nearbyint(snapEigen.rows() / (snapshot.mesh().V()).size());
305 Eigen::VectorXd vol3 = volumes.replicate(dim, 1);
310 GeometricField<scalar, fvPatchField, volMesh>& snapshot);
312 GeometricField<vector, fvPatchField, volMesh>& snapshot);
314 GeometricField<tensor, fvPatchField, volMesh>& snapshot);
316template<
class Type,
template<
class>
class PatchField,
class GeoMesh>
317Eigen::VectorXd
getCoeffs(GeometricField<Type, PatchField, GeoMesh>&
319 PtrList<GeometricField<Type, PatchField, GeoMesh>>& modes, label Nmodes,
320 bool consider_volumes)
326 Msize = modes.size();
334 "The Number of requested modes is larger then the available quantity.");
336 Eigen::MatrixXd M_matrix =
getMassMatrix(modes, Nmodes, consider_volumes);
338 Eigen::VectorXd a(Msize);
339 Eigen::VectorXd b(Msize);
341 if (consider_volumes)
344 b = F.transpose().topRows(Msize) * V.asDiagonal() * snapEigen;
348 b = F.transpose().topRows(Msize) * snapEigen;
351 if (Pstream::parRun())
353 reduce(b, sumOp<Eigen::VectorXd>());
356 a = M_matrix.fullPivLu().solve(b);
361 GeometricField<scalar, fvPatchField, volMesh>&
362 snapshot, PtrList<GeometricField<scalar, fvPatchField, volMesh>>& modes,
364 bool consider_volumes);
367 GeometricField<scalar, fvsPatchField, surfaceMesh>&
368 snapshot, PtrList<GeometricField<scalar, fvsPatchField, surfaceMesh>>& modes,
370 bool consider_volumes =
false);
373 GeometricField<vector, fvPatchField, volMesh>&
374 snapshot, PtrList<GeometricField<vector, fvPatchField, volMesh>>& modes,
376 bool consider_volumes);
378template<
class Type,
template<
class>
class PatchField,
class GeoMesh>
379Eigen::MatrixXd
getCoeffs(PtrList<GeometricField<Type, PatchField, GeoMesh>>&
381 PtrList<GeometricField<Type, PatchField, GeoMesh>>& modes, label Nmodes,
382 bool consider_volumes)
388 Msize = modes.size();
396 "The Number of requested modes is larger then the available quantity.");
397 Eigen::MatrixXd coeff(Msize, snapshots.size());
399 for (
auto i = 0;
i < snapshots.size();
i++)
401 coeff.col(
i) =
getCoeffs(snapshots[
i], modes, Nmodes, consider_volumes);
408 PtrList<GeometricField<scalar, fvPatchField, volMesh>>&
409 snapshot, PtrList<GeometricField<scalar, fvPatchField, volMesh>>& modes,
411 bool consider_volumes);
414 PtrList<GeometricField<vector, fvPatchField, volMesh>>&
415 snapshot, PtrList<GeometricField<vector, fvPatchField, volMesh>>& modes,
417 bool consider_volumes);
420 PtrList<GeometricField<scalar, fvsPatchField, surfaceMesh>>&
421 snapshot, PtrList<GeometricField<scalar, fvsPatchField, surfaceMesh>>& modes,
423 bool consider_volumes);
426 acquiredSnapshotsTimes,
427 Eigen::MatrixXd parameters)
429 label parsNum = parameters.cols();
430 label parsSamplesNum = parameters.rows();
431 M_Assert(parsSamplesNum == acquiredSnapshotsTimes.size(),
432 "The list of time instants does not have the same number of vectors as the number of parameters samples");
433 Eigen::MatrixXd comb;
434 label totalSnapshotsNum = 0;
436 for (label k = 0; k < acquiredSnapshotsTimes.size(); k++)
438 totalSnapshotsNum += acquiredSnapshotsTimes[k].size();
441 comb.resize(totalSnapshotsNum, parsNum + 1);
444 for (label j = 0; j < acquiredSnapshotsTimes.size(); j++)
446 for (label k = 0; k < acquiredSnapshotsTimes[j].size(); k++)
448 comb(
i, parsNum) = (acquiredSnapshotsTimes[j])(k, 0);
449 comb.block(
i, 0, 1, parsNum) = parameters.row(j);
#define M_Assert(Expr, Msg)
Header file of the ITHACAcoeffsMass file.
static Eigen::VectorXd field2Eigen(GeometricField< tensor, PatchField, GeoMesh > &field)
Convert a vector OpenFOAM field into an Eigen Vector.
static Eigen::MatrixXd PtrList2Eigen(PtrList< GeometricField< Type, PatchField, GeoMesh > > &fields, label Nfields=-1)
Convert a PtrList of snapshots to Eigen matrix (only internal field)
Namespace to implement some useful assign operation of OF fields.
Eigen::VectorXd getCoeffs(GeometricField< Type, PatchField, GeoMesh > &snapshot, PtrList< GeometricField< Type, PatchField, GeoMesh > > &modes, label Nmodes, bool consider_volumes)
Projects a snapshot on a basis function and gets the coefficients of the projection.
PtrList< GeometricField< Type, PatchField, GeoMesh > > reconstructFromCoeff(PtrList< GeometricField< Type, PatchField, GeoMesh > > &modes, Eigen::MatrixXd &coeff_matrix, label Nmodes)
Exact reconstruction using a certain number of modes for a list of fields and the projection coeffici...
Eigen::VectorXd getMassMatrixFV(GeometricField< Type, PatchField, GeoMesh > &snapshot)
Gets a vector containing the volumes of each cell of the mesh.
Eigen::MatrixXd parTimeCombMat(List< Eigen::VectorXd > acquiredSnapshotsTimes, Eigen::MatrixXd parameters)
A method to compute the time-parameter combined matrix whose any single element corresponds to a uniq...
Eigen::MatrixXd getMassMatrix(PtrList< GeometricField< Type, PatchField, GeoMesh > > &modes, label Nmodes, bool consider_volumes)
Gets the mass matrix using the eigen routine.