libROM  v1.0
Data-driven physical simulation library
ParametricDMD.h
1 
11 // Description: Computes the ParametricDMD algorithm to obtain DMD model interpolant
12 // at desired parameter point by interpolation of DMD 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.
19 
20 #ifndef included_ParametricDMD_h
21 #define included_ParametricDMD_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 
51 template <class T>
52 void getParametricDMD(std::unique_ptr<T>& parametric_dmd,
53  const std::vector<Vector>& parameter_points,
54  std::vector<T*>& dmds,
55  const Vector & desired_point,
56  std::string rbf = "G",
57  std::string interp_method = "LS",
58  double closest_rbf_val = 0.9,
59  bool reorthogonalize_W = false)
60 {
61  CAROM_VERIFY(parameter_points.size() == dmds.size());
62  CAROM_VERIFY(dmds.size() > 1);
63  for (int i = 0; i < dmds.size() - 1; i++)
64  {
65  CAROM_VERIFY(dmds[i]->d_dt == dmds[i + 1]->d_dt);
66  CAROM_VERIFY(dmds[i]->d_k == dmds[i + 1]->d_k);
67  }
68  CAROM_VERIFY(closest_rbf_val >= 0.0 && closest_rbf_val <= 1.0);
69 
70  int mpi_init, rank;
71  MPI_Initialized(&mpi_init);
72  if (mpi_init == 0) {
73  MPI_Init(nullptr, nullptr);
74  }
75 
76  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
77 
78  std::vector<std::shared_ptr<CAROM::Matrix>> bases;
79  std::vector<std::shared_ptr<CAROM::Matrix>> A_tildes;
80  for (int i = 0; i < dmds.size(); i++)
81  {
82  bases.push_back(dmds[i]->d_basis);
83  A_tildes.push_back(dmds[i]->d_A_tilde);
84  }
85 
86  const int ref_point = getClosestPoint(parameter_points, desired_point);
87  std::vector<std::shared_ptr<CAROM::Matrix>> rotation_matrices =
88  obtainRotationMatrices(parameter_points, bases, ref_point);
89 
90  CAROM::MatrixInterpolator basis_interpolator(parameter_points,
91  rotation_matrices, bases, ref_point, "B", rbf, interp_method, closest_rbf_val);
92  std::shared_ptr<Matrix> W = basis_interpolator.interpolate(desired_point,
93  reorthogonalize_W);
94 
95  CAROM::MatrixInterpolator A_tilde_interpolator(parameter_points,
96  rotation_matrices, A_tildes, ref_point, "R", rbf, interp_method,
97  closest_rbf_val);
98  std::shared_ptr<Matrix> A_tilde = A_tilde_interpolator.interpolate(
99  desired_point);
100 
101  // Calculate the right eigenvalues/eigenvectors of A_tilde
102  ComplexEigenPair eigenpair = NonSymmetricRightEigenSolve(*A_tilde);
103  std::vector<std::complex<double>> eigs = eigenpair.eigs;
104 
105  // Calculate phi (phi = W * eigenvectors)
106  std::shared_ptr<CAROM::Matrix> phi_real = W->mult(*eigenpair.ev_real);
107  std::shared_ptr<CAROM::Matrix> phi_imaginary = W->mult(*eigenpair.ev_imaginary);
108 
109  parametric_dmd.reset(new T(eigs, phi_real, phi_imaginary, dmds[0]->d_k,
110  dmds[0]->d_dt, dmds[0]->d_t_offset,
111  dmds[0]->d_state_offset));
112 
113  delete eigenpair.ev_real;
114  delete eigenpair.ev_imaginary;
115 }
116 
135 template <class T>
136 void getParametricDMD(std::unique_ptr<T>& parametric_dmd,
137  const std::vector<Vector>& parameter_points,
138  std::vector<std::string>& dmd_paths,
139  const Vector & desired_point,
140  std::string rbf = "G",
141  std::string interp_method = "LS",
142  double closest_rbf_val = 0.9,
143  bool reorthogonalize_W = false)
144 {
145  std::vector<T*> dmds;
146  for (int i = 0; i < dmd_paths.size(); i++)
147  {
148  T* dmd = new T(dmd_paths[i]);
149  dmds.push_back(dmd);
150  }
151 
152  getParametricDMD(parametric_dmd, parameter_points, dmds, desired_point,
153  rbf, interp_method, closest_rbf_val, reorthogonalize_W);
154  for (int i = 0; i < dmds.size(); i++)
155  {
156  delete dmds[i];
157  }
158 }
159 
160 }
161 
162 #endif
std::shared_ptr< Matrix > interpolate(const Vector &point, bool orthogonalize=false)
Obtain the interpolated reduced matrix of the unsampled parameter point.
ComplexEigenPair NonSymmetricRightEigenSolve(const Matrix &A)
Computes the eigenvectors/eigenvalues of an NxN real nonsymmetric matrix.
Definition: Matrix.cpp:2031
std::vector< std::shared_ptr< Matrix > > obtainRotationMatrices(const std::vector< Vector > &parameter_points, const std::vector< std::shared_ptr< Matrix >> &bases, int ref_point)
Obtain the rotation matrices for all the parameter points using the basis of the reference point.
void getParametricDMD(std::unique_ptr< T > &parametric_dmd, const std::vector< Vector > &parameter_points, std::vector< T * > &dmds, const Vector &desired_point, std::string rbf="G", std::string interp_method="LS", double closest_rbf_val=0.9, bool reorthogonalize_W=false)
Constructor.
Definition: ParametricDMD.h:52
int getClosestPoint(const std::vector< const Vector * > &points, const Vector &test_point)
Get closest point to a test point among a group of points.
Definition: Vector.cpp:586
Matrix * ev_real
The real component of the eigenvectors in matrix form.
Definition: Matrix.h:1126
std::vector< std::complex< double > > eigs
The corresponding complex eigenvalues.
Definition: Matrix.h:1136
Matrix * ev_imaginary
The imaginary component of the eigenvectors in matrix form.
Definition: Matrix.h:1131