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;
37 for (label k = 0; k < coeff_matrix.cols(); k++)
39 for (label
i = 0;
i < Nmodes;
i++)
42 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)
83 "The Number of requested modes is larger then the available quantity.");
85 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)
144 Msize = modes.size();
145 Msize2 = modes2.size();
154 "The Number of requested modes is larger then the available quantity.");
156 "The Number of requested modes is larger then the available quantity.");
159 Eigen::MatrixXd M = Eigen::MatrixXd::Zero(Msize, Msize2);
161 if (consider_volumes)
168 for (
int i = 0;
i < V.size();
i++)
170 M += V(
i) * F.transpose().topRows(Msize).col(
i) * F2.leftCols(Msize2).row(
i);
176 M = F.transpose().topRows(Msize) * V.asDiagonal() * F2.leftCols(Msize2);
181 M = F.transpose().topRows(Msize) * F2.leftCols(Msize2);
184 if (Pstream::parRun())
186 reduce(M, sumOp<Eigen::MatrixXd>());
193 PtrList<GeometricField<scalar, fvPatchField, volMesh >> & modes,
194 PtrList<GeometricField<scalar, fvPatchField, volMesh >>& modes2, label Nmodes,
195 bool consider_volumes);
198 PtrList<GeometricField<scalar, fvsPatchField, surfaceMesh >> & modes,
199 PtrList<GeometricField<scalar, fvsPatchField, surfaceMesh >>& modes2,
201 bool consider_volumes =
false);
204 PtrList<GeometricField<vector, fvPatchField, volMesh >> & modes,
205 PtrList<GeometricField<vector, fvPatchField, volMesh >>& modes2, label Nmodes,
206 bool consider_volumes);
209 PtrList<GeometricField<tensor, fvPatchField, volMesh >> & modes,
210 PtrList<GeometricField<tensor, fvPatchField, volMesh >>& modes2, label Nmodes,
211 bool consider_volumes);
214template<
class Type,
template<
class>
class PatchField,
class GeoMesh>
216 PtrList<GeometricField<Type, PatchField, GeoMesh >>
218 PtrList<GeometricField<Type, PatchField, GeoMesh >>& modes2,
219 Eigen::VectorXd weights,
221 bool consider_volumes)
227 Msize = modes.size();
228 Msize2 = modes2.size();
237 "The Number of requested modes is larger then the available quantity.");
239 "The Number of requested modes is larger then the available quantity.");
242 Eigen::MatrixXd M = Eigen::MatrixXd::Zero(Msize, Msize2);
244 if (consider_volumes)
251 for (
int i = 0;
i < V.size();
i++)
253 M += (V(
i) * weights(
i)) * F.transpose().topRows(Msize).col(
i) * F2.leftCols(
260 M = F.transpose().topRows(Msize) * V.asDiagonal() * ( weights.asDiagonal()
261 * F2.leftCols(Msize2) );
266 M = F.transpose().topRows(Msize) * weights.asDiagonal() * F2.leftCols(Msize2);
269 if (Pstream::parRun())
271 reduce(M, sumOp<Eigen::MatrixXd>());
278 PtrList<GeometricField<scalar, fvPatchField, volMesh >> & modes,
279 PtrList<GeometricField<scalar, fvPatchField, volMesh >>& modes2,
280 Eigen::VectorXd weights,
282 bool consider_volumes);
285 PtrList<GeometricField<scalar, fvsPatchField, surfaceMesh >> & modes,
286 PtrList<GeometricField<scalar, fvsPatchField, surfaceMesh >>& modes2,
287 Eigen::VectorXd weights,
289 bool consider_volumes);
292 PtrList<GeometricField<vector, fvPatchField, volMesh >> & modes,
293 PtrList<GeometricField<vector, fvPatchField, volMesh >>& modes2,
294 Eigen::VectorXd weights,
296 bool consider_volumes);
299 PtrList<GeometricField<tensor, fvPatchField, volMesh >> & modes,
300 PtrList<GeometricField<tensor, fvPatchField, volMesh >>& modes2,
301 Eigen::VectorXd weights,
303 bool consider_volumes);
306template<
class Type,
template<
class>
class PatchField,
class GeoMesh>
308 GeometricField<Type, PatchField, GeoMesh>& snapshot)
311 label dim = std::nearbyint(snapEigen.rows() / (snapshot.mesh().V()).size());
313 Eigen::VectorXd vol3 = volumes.replicate(dim, 1);
318 GeometricField<scalar, fvPatchField, volMesh>& snapshot);
320 GeometricField<vector, fvPatchField, volMesh>& snapshot);
322 GeometricField<tensor, fvPatchField, volMesh>& snapshot);
324template<
class Type,
template<
class>
class PatchField,
class GeoMesh>
325Eigen::VectorXd
getCoeffs(GeometricField<Type, PatchField, GeoMesh>&
327 PtrList<GeometricField<Type, PatchField, GeoMesh >> & modes, label Nmodes,
328 bool consider_volumes)
333 Msize = modes.size();
341 "The Number of requested modes is larger then the available quantity.");
343 Eigen::MatrixXd M_matrix =
getMassMatrix(modes, Nmodes, consider_volumes);
345 Eigen::VectorXd a(Msize);
346 Eigen::VectorXd b(Msize);
348 if (consider_volumes)
351 b = F.transpose().topRows(Msize) * V.asDiagonal() * snapEigen;
355 b = F.transpose().topRows(Msize) * snapEigen;
358 if (Pstream::parRun())
360 reduce(b, sumOp<Eigen::VectorXd>());
363 a = M_matrix.fullPivLu().solve(b);
368 GeometricField<scalar, fvPatchField, volMesh>&
369 snapshot, PtrList<GeometricField<scalar, fvPatchField, volMesh >> & modes,
371 bool consider_volumes);
374 GeometricField<scalar, fvsPatchField, surfaceMesh>&
375 snapshot, PtrList<GeometricField<scalar, fvsPatchField, surfaceMesh >> & modes,
377 bool consider_volumes =
false);
380 GeometricField<vector, fvPatchField, volMesh>&
381 snapshot, PtrList<GeometricField<vector, fvPatchField, volMesh >> & modes,
383 bool consider_volumes);
385template<
class Type,
template<
class>
class PatchField,
class GeoMesh >
386Eigen::MatrixXd
getCoeffs(PtrList<GeometricField<Type, PatchField, GeoMesh >> &
388 PtrList<GeometricField<Type, PatchField, GeoMesh >>& modes, label Nmodes,
389 bool consider_volumes)
395 Msize = modes.size();
403 "The Number of requested modes is larger then the available quantity.");
404 Eigen::MatrixXd coeff(Msize, snapshots.size());
406 for (
auto i = 0;
i < snapshots.size();
i++)
408 coeff.col(
i) =
getCoeffs(snapshots[
i], modes, Nmodes, consider_volumes);
415 PtrList<GeometricField<scalar, fvPatchField, volMesh >> &
416 snapshot, PtrList<GeometricField<scalar, fvPatchField, volMesh >>& modes,
418 bool consider_volumes);
421 PtrList<GeometricField<vector, fvPatchField, volMesh >> &
422 snapshot, PtrList<GeometricField<vector, fvPatchField, volMesh >>& modes,
424 bool consider_volumes);
427 PtrList<GeometricField<scalar, fvsPatchField, surfaceMesh >> &
428 snapshot, PtrList<GeometricField<scalar, fvsPatchField, surfaceMesh >>& modes,
430 bool consider_volumes);
433 acquiredSnapshotsTimes,
434 Eigen::MatrixXd parameters)
436 label parsNum = parameters.cols();
437 label parsSamplesNum = parameters.rows();
438 M_Assert(parsSamplesNum == acquiredSnapshotsTimes.size(),
439 "The list of time instants does not have the same number of vectors as the number of parameters samples");
440 Eigen::MatrixXd comb;
441 label totalSnapshotsNum = 0;
443 for (label k = 0; k < acquiredSnapshotsTimes.size(); k++)
445 totalSnapshotsNum += acquiredSnapshotsTimes[k].size();
448 comb.resize(totalSnapshotsNum, parsNum + 1);
451 for (label j = 0; j < acquiredSnapshotsTimes.size(); j++)
453 for (label k = 0; k < acquiredSnapshotsTimes[j].size(); k++)
455 comb(
i, parsNum) = (acquiredSnapshotsTimes[j])(k, 0);
456 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.