36template<
class Type,
template<
class>
class PatchField,
class GeoMesh>
38 PtrList<GeometricField<Type, PatchField, GeoMesh >>& snapshots,
double dt)
45 redSVD = para->ITHACAdict->lookupOrDefault<
bool>(
"redSVD",
false);
49template<
class Type,
template<
class>
class PatchField,
class GeoMesh>
59 std::string assertMessage =
"The SVD_rank is equal to: " + name(
61 ", it cannot be bigger than the number of snapshots - 1. NSnapshots is equal to: "
64 M_Assert(SVD_rank <
NSnaps, assertMessage.c_str());
68 Eigen::MatrixXd Xm = SnapEigen.leftCols(
NSnaps - 1);
69 Eigen::MatrixXd Ym = SnapEigen.rightCols(
NSnaps - 1);
70 List<Eigen::MatrixXd> XmBC(SnapEigenBC.size());
71 List<Eigen::MatrixXd> YmBC(SnapEigenBC.size());
73 for (label i = 0 ; i < SnapEigenBC.size() ; i++)
75 XmBC[i] = SnapEigenBC[i].leftCols(
NSnaps - 1);
76 YmBC[i] = SnapEigenBC[i].rightCols(
NSnaps - 1);
85 Info <<
"SVD using Randomized method" << endl;
86 RedSVD::RedSVD<Eigen::MatrixXd> svd(Xm, SVD_rank);
89 S = svd.singularValues().array().cwiseInverse();
93 Info <<
"SVD using JacobiSVD" << endl;
94 Eigen::JacobiSVD<Eigen::MatrixXd> svd(Xm,
95 Eigen::ComputeThinU | Eigen::ComputeThinV);
96 U = svd.matrixU().leftCols(SVD_rank);
97 V = svd.matrixV().leftCols(SVD_rank);
98 S = svd.singularValues().head(SVD_rank).array().cwiseInverse();
101 Eigen::MatrixXcd A_tilde = U.transpose().conjugate() * Ym *
104 Eigen::ComplexEigenSolver<Eigen::MatrixXcd> esEg(A_tilde);
106 Eigen::VectorXd ln =
eigenValues.array().log().imag().abs();
108 typedef std::pair<double, label> mypair;
109 std::vector<mypair> sortedList(ln.size());
111 for (label i = 0; i < ln.size(); i++)
113 sortedList[i].first = ln(i);
114 sortedList[i].second = i;
117 std::sort(sortedList.begin(), sortedList.end(),
118 std::less<std::pair<double, label >> ());
122 DMDEigenModes = Ym * V * S.asDiagonal() * esEg.eigenvectors();
125 for (label i = 0; i < YmBC.size(); i++)
127 DMDEigenModesBC[i] = YmBC[i] * V * S.asDiagonal() * esEg.eigenvectors();
132 Eigen::VectorXd eigenValueseigLam =
134 PODm = (Xm * V) * eigenValueseigLam.asDiagonal();
135 PODmBC.resize(XmBC.size());
137 for (label i = 0; i < XmBC.size(); i++)
139 PODmBC[i] = (XmBC[i] * V) * eigenValueseigLam.asDiagonal();
145 for (label i = 0; i <
PODmBC.size(); i++)
156 Info <<
"exporting the DMDmodes for " <<
snapshotsDMD[0].name() << endl;
158 snapshotsDMD[0].name() +
"_Modes_" + name(SVD_rank) +
"_Real");
160 snapshotsDMD[0].name() +
"_Modes_" + name(SVD_rank) +
"_Imag");
164template<
class Type,
template<
class>
class PatchField,
class GeoMesh >
166 double tFinal,
double dt)
169 label ncols =
static_cast<label
>((tFinal - tStart) / dt ) + 1;
173 for (
double t = tStart; t <= tFinal; t += dt)
175 Eigen::VectorXcd coli = (omega * t).array().exp() *
Amplitudes.array();
182template<
class Type,
template<
class>
class PatchField,
class GeoMesh>
187 std::string path = exportFolder +
"/eigs.npy";
188 cnpy::save(eigs, path);
193template<
class Type,
template<
class>
class PatchField,
class GeoMesh>
197 PtrList<GeometricField<Type, PatchField, GeoMesh >> snapshotsrec;
199 for (label i = 0; i <
dynamics.cols(); i++)
202 Eigen::VectorXd vec = col.real();
203 GeometricField<Type, PatchField, GeoMesh> tmp2(
"TMP",
207 for (label k = 0; k < tmp2.boundaryField().size(); k++)
213 snapshotsrec.append(tmp2.clone());
219template<
class Type,
template<
class>
class PatchField,
class GeoMesh>
224 GeometricField<Type, PatchField, GeoMesh> tmp2Real(
226 GeometricField<Type, PatchField, GeoMesh> tmp2Imag(
237 for (label k = 0; k < tmp2Real.boundaryField().size(); k++)
Header file of the ITHACADMD class.
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.
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.
static Eigen::MatrixXd PtrList2Eigen(PtrList< GeometricField< Type, PatchField, GeoMesh > > &fields, label Nfields=-1)
Convert a PtrList of snapshots to Eigen matrix (only internal field).
Class of the computation of the DMD, it exploits the SVD methods.
PtrList< GeometricField< Type, PatchField, GeoMesh > > snapshotsDMD
PtrList of OpenFOAM GeoometricFields where the snapshots are stored.
void convert2Foam()
Convert the EigenModes in Matrix form into OpenFOAM GeometricFields.
label SVD_rank_public
Rank of the DMD.
ITHACADMD(PtrList< GeometricField< Type, PatchField, GeoMesh > > &snapshots, double dt)
Constructs the object.
Eigen::VectorXd Amplitudes
Amplitudes of DMD.
void getDynamics(double tStart, double tFinal, double dt)
Export the dynamics of DMD given an initial time step, a final one and a time step.
double originalDT
Original time step used to acquire the snapshots.
void reconstruct(word exportFolder, word fieldName)
Reconstruct and export the solution using the computed dynamics.
Eigen::MatrixXcd dynamics
Complex Eigen::Matrix used to store the Dynamics of the DMD modes.
List< Eigen::MatrixXcd > PODmBC
List of complex matrices used to store the POD modes on the boundaries, used only for compution in th...
void exportEigs(word exportFolder)
Export the eigenvalues in numpy format.
Modes< Type, PatchField, GeoMesh > DMDmodesImag
Modes object used to store the Imaginary part of the DMD modes.
List< Eigen::MatrixXcd > DMDEigenModesBC
DMD modes on the boundary stored in a List of complex Eigen::Matrix, it is the object used for comput...
label NSnaps
Number of snapshots.
void getModes(label SVD_rank=-1, bool exact=true, bool exportDMDmodes=false)
Get the DMD modes.
Modes< Type, PatchField, GeoMesh > DMDmodesReal
Modes object used to store the Real part of the DMD modes.
Eigen::VectorXcd eigenValues
Eigenvalues of the dynamics mode decomposition.
bool redSVD
If true, it uses the Randomized SVD.
Eigen::MatrixXcd PODm
Complex matrix used to store the POD modes, used only for compution in the projected approach.
Eigen::MatrixXcd DMDEigenModes
DMD modes stored in a complex Eigen::Matrix, it is the object used for computations.
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.
void exportFields(PtrList< GeometricField< Type, PatchField, GeoMesh > > &field, word folder, word fieldname)
Function to export a scalar of vector field.
void assignBC(GeometricField< scalar, fvPatchField, volMesh > &s, label BC_ind, double value)
Assign uniform Boundary Condition to a volScalarField.