MAST
Multidisciplinary-design Adaptation and Sensitivity Toolkit (MAST)
lapack_dgeev_interface.cpp
Go to the documentation of this file.
1 /*
2  * MAST: Multidisciplinary-design Adaptation and Sensitivity Toolkit
3  * Copyright (C) 2013-2020 Manav Bhatia and MAST authors
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18  */
19 
20 
21 // MAST includes
23 
24 
25 void
27  bool computeEigenvectors) {
28 
29  libmesh_assert(A.cols() == A.rows());
30 
31  _A = A;
32 
34  Amat = A;
35 
36  int n = (int)A.cols();
37 
38  char L='N',R='N';
39 
40  if (computeEigenvectors) {
41 
42  L = 'V'; R = 'V';
43  VL.setZero(n, n);
44  VR.setZero(n, n);
45  }
46 
47  int
48  lwork=16*n;
49 
50  info_val=-1;
51 
53  work,
54  w_r,
55  w_i;
56 
58  vecl,
59  vecr;
60 
61  W.setZero(n);
62  work.setZero(lwork);
63  w_r.setZero(n);
64  w_i.setZero(n);
65  vecl.setZero(n,n);
66  vecr.setZero(n,n);
67 
68  Real
69  *a_vals = Amat.data(),
70  *w_r_v = w_r.data(),
71  *w_i_v = w_i.data(),
72  *vecl_v = vecl.data(),
73  *vecr_v = vecr.data(),
74  *work_v = work.data();
75 
76 
77  dgeev_(&L, &R, &n,
78  &(a_vals[0]), &n,
79  &(w_r_v[0]), &(w_i_v[0]),
80  &(vecl_v[0]), &n, &(vecr_v[0]), &n,
81  &(work_v[0]), &lwork,
82  &info_val);
83 
84  // now sort the eigenvalues for complex conjugates
85  unsigned int n_located = 0;
86  while (n_located < n) {
87 
88  // if the imaginary part of the eigenvalue is non-zero, it is a
89  // complex conjugate
90  if (w_i(n_located) != 0.) { // complex conjugate
91 
92  W( n_located) = std::complex<double>(w_r(n_located), w_i(n_located));
93  W(1+n_located) = std::complex<double>(w_r(n_located), -w_i(n_located));
94 
95  // copy the eigenvectors if they were requested
96  if (computeEigenvectors) {
97 
98  std::complex<double> iota = std::complex<double>(0, 1.);
99 
100  VL.col( n_located) = (vecl.col( n_located).cast<Complex>() +
101  vecl.col(1+n_located).cast<Complex>() * iota);
102  VL.col(1+n_located) = (vecl.col( n_located).cast<Complex>() -
103  vecl.col(1+n_located).cast<Complex>() * iota);
104  VR.col( n_located) = (vecr.col( n_located).cast<Complex>() +
105  vecr.col(1+n_located).cast<Complex>() * iota);
106  VR.col(1+n_located) = (vecr.col( n_located).cast<Complex>() -
107  vecr.col(1+n_located).cast<Complex>() * iota);
108  }
109 
110  // two complex conjugate roots were found
111  n_located +=2;
112  }
113  else {
114 
115  W( n_located) = std::complex<double>(w_r(n_located), 0.);
116 
117  // copy the eigenvectors if they were requested
118  if (computeEigenvectors) {
119 
120  VL.col(n_located) = vecl.col(n_located).cast<Complex>();
121  VR.col(n_located) = vecr.col(n_located).cast<Complex>();
122  }
123 
124  // only one real root was found
125  n_located++;
126  }
127  }
128 
129  if (info_val != 0)
130  libMesh::out
131  << "Warning!! DGEEV returned with nonzero info = "
132  << info_val << std::endl;
133 }
134 
135 
libMesh::Real Real
void dgeev_(const char *jobvl, const char *jobvr, int *n, double *a, int *lda, double *w_r, double *w_i, double *vl, int *ldvl, double *vr, int *ldvr, double *work, int *lwork, int *info)
libMesh::Complex Complex
Matrix< Real, Dynamic, Dynamic > RealMatrixX
void compute(const RealMatrixX &A, bool computeEigenvectors=true)
computes the eigensolution for .
Matrix< Real, Dynamic, 1 > RealVectorX
const RealMatrixX & A() const