libROM  v1.0
Data-driven physical simulation library
ParametricDMDc.h
1 
11 // Description: Computes the ParametricDMDc algorithm to obtain DMDc model interpolant
12 // at desired parameter point by interpolation of DMDc models at training parameter points.
13 // The implemented dynamic mode decomposition algorithm is derived from
14 // Tu et. al's paper "On Dynamic Mode Decomposition: Theory and
15 // Applications": https://arxiv.org/abs/1312.0041
16 // The interpolation algorithm was adapted from "Gradient-based
17 // Constrained Optimization Using a Database of Linear Reduced-Order Models"
18 // by Y. Choi et al. We extend this algorithm to DMDc.
19 
20 #ifndef included_ParametricDMDc_h
21 #define included_ParametricDMDc_h
22 
23 #include "manifold_interp/MatrixInterpolator.h"
24 #include "linalg/Matrix.h"
25 #include "linalg/Vector.h"
26 #include "mpi.h"
27 
28 #include <complex>
29 
30 namespace CAROM {
31 
55 template <class T>
56 void getParametricDMDc(T*& parametric_dmdc,
57  std::vector<Vector*>& parameter_points,
58  std::vector<T*>& dmdcs,
59  std::vector<Matrix*> controls,
60  Matrix*& controls_interpolated,
61  Vector* desired_point,
62  std::string rbf = "G",
63  std::string interp_method = "LS",
64  double closest_rbf_val = 0.9,
65  bool reorthogonalize_W = false)
66 {
67  CAROM_VERIFY(parameter_points.size() == dmdcs.size());
68  CAROM_VERIFY(dmdcs.size() > 1);
69  for (int i = 0; i < dmdcs.size() - 1; i++)
70  {
71  CAROM_VERIFY(dmdcs[i]->d_dt == dmdcs[i + 1]->d_dt);
72  CAROM_VERIFY(dmdcs[i]->d_k == dmdcs[i + 1]->d_k);
73  }
74  CAROM_VERIFY(closest_rbf_val >= 0.0 && closest_rbf_val <= 1.0);
75 
76  int mpi_init, rank;
77  MPI_Initialized(&mpi_init);
78  if (mpi_init == 0) {
79  MPI_Init(nullptr, nullptr);
80  }
81 
82  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
83 
84  std::vector<CAROM::Matrix*> bases;
85  std::vector<CAROM::Matrix*> A_tildes;
86  std::vector<CAROM::Matrix*> B_tildes;
87  for (int i = 0; i < dmdcs.size(); i++)
88  {
89  bases.push_back(dmdcs[i]->d_basis);
90  A_tildes.push_back(dmdcs[i]->d_A_tilde);
91  B_tildes.push_back(dmdcs[i]->d_B_tilde);
92  }
93 
94  int ref_point = getClosestPoint(parameter_points, desired_point);
95  std::vector<CAROM::Matrix*> rotation_matrices = obtainRotationMatrices(
96  parameter_points,
97  bases, ref_point);
98 
99  CAROM::MatrixInterpolator basis_interpolator(parameter_points,
100  rotation_matrices, bases, ref_point, "B", rbf, interp_method, closest_rbf_val);
101  CAROM::Matrix* W = basis_interpolator.interpolate(desired_point,
102  reorthogonalize_W);
103 
104  CAROM::MatrixInterpolator A_tilde_interpolator(parameter_points,
105  rotation_matrices, A_tildes, ref_point, "R", rbf, interp_method,
106  closest_rbf_val);
107  CAROM::Matrix* A_tilde = A_tilde_interpolator.interpolate(desired_point);
108 
109  CAROM::MatrixInterpolator B_tilde_interpolator(parameter_points,
110  rotation_matrices, B_tildes, ref_point, "R", rbf, interp_method,
111  closest_rbf_val);
112  CAROM::Matrix* B_tilde = B_tilde_interpolator.interpolate(desired_point);
113 
114  CAROM::MatrixInterpolator control_interpolator(parameter_points,
115  rotation_matrices, controls, ref_point, "R", rbf, interp_method,
116  closest_rbf_val);
117 
118  controls_interpolated = control_interpolator.interpolate(desired_point);
119 
120  // Calculate the right eigenvalues/eigenvectors of A_tilde
121  ComplexEigenPair eigenpair = NonSymmetricRightEigenSolve(A_tilde);
122  std::vector<std::complex<double>> eigs = eigenpair.eigs;
123 
124  // Calculate phi (phi = W * eigenvectors)
125  CAROM::Matrix* phi_real = W->mult(eigenpair.ev_real);
126  CAROM::Matrix* phi_imaginary = W->mult(eigenpair.ev_imaginary);
127 
128  parametric_dmdc = new T(eigs, phi_real, phi_imaginary, B_tilde,
129  dmdcs[0]->d_k,dmdcs[0]->d_dt,
130  dmdcs[0]->d_t_offset, dmdcs[0]->d_state_offset, W);
131 
132  delete A_tilde;
133  delete eigenpair.ev_real;
134  delete eigenpair.ev_imaginary;
135 
136  for (auto m : rotation_matrices)
137  delete m;
138 
139 }
140 
163 template <class T>
164 void getParametricDMDc(T*& parametric_dmdc,
165  std::vector<Vector*>& parameter_points,
166  std::vector<std::string>& dmdc_paths,
167  std::vector<Matrix*> controls,
168  Matrix*& controls_interpolated,
169  Vector* desired_point,
170  std::string rbf = "G",
171  std::string interp_method = "LS",
172  double closest_rbf_val = 0.9,
173  bool reorthogonalize_W = false)
174 {
175  std::vector<T*> dmdcs;
176  for (int i = 0; i < dmdc_paths.size(); i++)
177  {
178  T* dmdc = new T(dmdc_paths[i]);
179  dmdcs.push_back(dmdc);
180  }
181 
182  getParametricDMDc(parametric_dmdc, parameter_points, dmdcs, controls,
183  controls_interpolated,
184  desired_point,
185  rbf, interp_method, closest_rbf_val,
186  reorthogonalize_W);
187 
188  for (int i = 0; i < dmdcs.size(); i++)
189  {
190  delete dmdcs[i];
191  }
192 }
193 
194 }
195 
196 #endif
Matrix * mult(const Matrix &other) const
Multiplies this Matrix with other and returns the product, reference version.
Definition: Matrix.h:283
Matrix * interpolate(Vector *point, bool orthogonalize=false)
Obtain the interpolated reduced matrix of the unsampled parameter point.
void getParametricDMDc(T *&parametric_dmdc, std::vector< Vector * > &parameter_points, std::vector< T * > &dmdcs, std::vector< Matrix * > controls, Matrix *&controls_interpolated, Vector *desired_point, std::string rbf="G", std::string interp_method="LS", double closest_rbf_val=0.9, bool reorthogonalize_W=false)
Constructor.
struct ComplexEigenPair NonSymmetricRightEigenSolve(Matrix *A)
Computes the eigenvectors/eigenvalues of an NxN real nonsymmetric matrix.
Definition: Matrix.cpp:2203
int getClosestPoint(std::vector< Vector * > &points, Vector *test_point)
Get closest point to a test point among a group of points.
Definition: Vector.cpp:647
std::vector< Matrix * > obtainRotationMatrices(std::vector< Vector * > parameter_points, std::vector< Matrix * > bases, int ref_point)
Obtain the rotation matrices for all the parameter points using the basis of the reference point.
Matrix * ev_real
The real component of the eigenvectors in matrix form.
Definition: Matrix.h:1376
std::vector< std::complex< double > > eigs
The corresponding complex eigenvalues.
Definition: Matrix.h:1386
Matrix * ev_imaginary
The imaginary component of the eigenvectors in matrix form.
Definition: Matrix.h:1381