1 #ifndef SELDON_FILE_EIGENVALUE_SOLVER_CXX
3 #include "EigenvalueSolver.hxx"
14 template<
class T,
class MatStiff,
class MatMass>
17 eigenvalue_computation_mode = 1;
18 nb_eigenvalues_wanted = 0;
19 nb_add_eigenvalues = 0;
21 type_spectrum_wanted = LARGE_EIGENVALUES;
22 type_sort_eigenvalues = SORTED_MODULUS;
25 diagonal_mass =
false;
26 stopping_criterion = 1e-6;
27 nb_maximum_iterations = 1000;
34 nb_arnoldi_vectors = 0;
35 automatic_selection_arnoldi_vectors =
true;
39 complex_system =
false;
43 #ifdef SELDON_WITH_MPI
45 comm = MPI_COMM_WORLD;
48 type_solver = SOLVER_LOBPCG;
49 ortho_manager = ORTHO_DGKS;
56 template<
class T,
class MatStiff,
class MatMass>
64 #ifdef SELDON_WITH_MPI
65 MPI_Allreduce(&n, &nglob, 1, MPI_INTEGER, MPI_SUM, comm);
68 if (nb_eigenvalues_wanted >= (nglob - 2))
70 cout <<
"Too many wanted eigenvalues " << endl;
71 cout << nb_eigenvalues_wanted <<
72 " asked eigenvalues, but the rank of the matrix is lower than "
78 if (automatic_selection_arnoldi_vectors)
79 nb_arnoldi_vectors = min(nglob, 2*nb_eigenvalues_wanted+2);
91 template<
class T,
class MatStiff,
class MatMass>
97 this->diagonal_mass =
true;
103 this->diagonal_mass =
false;
106 this->Init(K.GetM());
115 template<
class T,
class MatStiff,
class MatMass>
121 this->diagonal_mass =
false;
122 this->Init(K.GetM());
132 template<
class T,
class MatStiff,
class MatMass>
135 return eigenvalue_computation_mode;
140 template<
class T,
class MatStiff,
class MatMass>
143 eigenvalue_computation_mode = mode;
148 template<
class T,
class MatStiff,
class MatMass>
151 return nb_eigenvalues_wanted;
156 template<
class T,
class MatStiff,
class MatMass>
159 return nb_add_eigenvalues;
164 template<
class T,
class MatStiff,
class MatMass>
172 template<
class T,
class MatStiff,
class MatMass>
180 template<
class T,
class MatStiff,
class MatMass>
183 return restart_number;
188 template<
class T,
class MatStiff,
class MatMass>
196 template<
class T,
class MatStiff,
class MatMass>
199 return ortho_manager;
204 template<
class T,
class MatStiff,
class MatMass>
212 template<
class T,
class MatStiff,
class MatMass>
219 #ifdef SELDON_WITH_MPI
220 template<
class T,
class MatStiff,
class MatMass>
228 template<
class T,
class MatStiff,
class MatMass>
229 void EigenProblem_Base<T, MatStiff, MatMass>::SetCommunicator(MPI_Comm& comm_)
236 template<
class T,
class MatStiff,
class MatMass>
239 nb_eigenvalues_wanted = n;
244 template<
class T,
class MatStiff,
class MatMass>
247 nb_add_eigenvalues = n;
252 template<
class T,
class MatStiff,
class MatMass>
255 return type_spectrum_wanted;
260 template<
class T,
class MatStiff,
class MatMass>
263 return type_sort_eigenvalues;
273 template<
class T,
class MatStiff,
class MatMass>
287 template<
class T,
class MatStiff,
class MatMass>
295 template<
class T,
class MatStiff,
class MatMass>
303 template<
class T,
class MatStiff,
class MatMass>
315 template<
class T,
class MatStiff,
class MatMass>
319 type_spectrum_wanted = type;
321 type_sort_eigenvalues = type_sort;
330 template<
class T,
class MatStiff,
class MatMass>
336 type_spectrum_wanted = type;
338 shift_imag = imag(val);
347 this->diagonal_mass =
false;
351 type_sort_eigenvalues = type_sort;
356 template<
class T,
class MatStiff,
class MatMass>
360 return emin_interval;
365 template<
class T,
class MatStiff,
class MatMass>
369 return emax_interval;
374 template<
class T,
class MatStiff,
class MatMass>
385 template<
class T,
class MatStiff,
class MatMass>
394 template<
class T,
class MatStiff,
class MatMass>
403 template<
class T,
class MatStiff,
class MatMass>
406 diagonal_mass = diag;
411 template<
class T,
class MatStiff,
class MatMass>
414 return diagonal_mass;
419 template<
class T,
class MatStiff,
class MatMass>
423 stopping_criterion = eps;
428 template<
class T,
class MatStiff,
class MatMass>
432 return stopping_criterion;
437 template<
class T,
class MatStiff,
class MatMass>
440 nb_maximum_iterations = n;
445 template<
class T,
class MatStiff,
class MatMass>
449 return nb_maximum_iterations;
455 template<
class T,
class MatStiff,
class MatMass>
464 template<
class T,
class MatStiff,
class MatMass>
467 return nb_arnoldi_vectors;
472 template<
class T,
class MatStiff,
class MatMass>
475 automatic_selection_arnoldi_vectors =
false;
476 nb_arnoldi_vectors = n;
481 template<
class T,
class MatStiff,
class MatMass>
489 template<
class T,
class MatStiff,
class MatMass>
497 template<
class T,
class MatStiff,
class MatMass>
505 template<
class T,
class MatStiff,
class MatMass>
513 template<
class T,
class MatStiff,
class MatMass>
517 if (print_level >= 3)
520 #ifdef SELDON_WITH_MPI
521 if (comm.Get_rank() == 0)
523 cout<<
" Iteration number " << nb_prod << endl;
525 else if (print_level >= 1)
527 if (nb_prod%100 == 0)
528 #ifdef SELDON_WITH_MPI
529 if (comm.Get_rank() == 0)
531 cout<<
" Iteration number " << nb_prod << endl;
537 template<
class T,
class MatStiff,
class MatMass>
540 cout <<
"InitMatrix has not been called" << endl;
546 template<
class T,
class MatStiff,
class MatMass>
567 template<
class T,
class MatStiff,
class MatMass>
603 template<
class T,
class MatStiff,
class MatMass>
606 for (
int i = 0; i < sqrt_diagonal_mass.GetM(); i++)
607 sqrt_diagonal_mass(i) = sqrt(sqrt_diagonal_mass(i));
612 template<
class T,
class MatStiff,
class MatMass>
template<
class T0>
616 for (
int i = 0; i < X.GetM(); i++)
617 X(i) /= sqrt_diagonal_mass(i);
622 template<
class T,
class MatStiff,
class MatMass>
template<
class T0>
626 for (
int i = 0; i < X.GetM(); i++)
627 X(i) *= sqrt_diagonal_mass(i);
632 template<
class T,
class MatStiff,
class MatMass>
639 sqrt_diagonal_mass.Reallocate(this->n_);
640 sqrt_diagonal_mass.Fill(1.0);
644 sqrt_diagonal_mass.Reallocate(this->n_);
645 for (
int i = 0; i < this->n_; i++)
646 sqrt_diagonal_mass(i) = (*Mh)(i, i);
652 template<
class T,
class MatStiff,
class MatMass>
662 template<
class T,
class MatStiff,
class MatMass>
670 template<
class T,
class MatStiff,
class MatMass>
690 template<
class T,
class MatStiff,
class MatMass>
698 template<
class T,
class MatStiff,
class MatMass>
707 template<
class T,
class MatStiff,
class MatMass>
719 template<
class T,
class MatStiff,
class MatMass>
729 if (coef_mass != T(0))
732 for (
int i = 0; i < Y.GetM(); i++)
733 Y(i) += coef_mass*X(i);
735 MltAdd(coef_mass, *Mh, X, coef_stiff, Y);
739 if (coef_stiff != T(1))
756 template<
class T,
class MatStiff,
class MatMass>
769 template<
class T,
class MatStiff,
class MatMass>
779 template<
class T,
class MatStiff,
class MatMass>
template<
class T0>
788 template<
class T,
class MatStiff,
class MatMass>
789 template<
class TransA,
class T0>
798 template<
class T,
class MatStiff,
class MatMass>
806 template<
class T,
class MatStiff,
class MatMass>
807 template<
class TransStatus>
816 template<
class T,
class MatStiff,
class MatMass>
817 template<
class TransStatus>
826 template<
class T,
class MatStiff,
class MatMass>
829 sqrt_diagonal_mass.Clear();
845 template<
class EigenPb,
class Vector1,
class Matrix1,
class T0>
847 Matrix1& eigen_vectors,
848 const T0& shiftr,
const T0& shifti)
851 if (var.DiagonalMass())
854 for (
int i = 0; i < var.sqrt_diagonal_mass.GetM(); i++)
855 for (
int j = 0; j < eigen_vectors.GetN(); j++)
856 eigen_vectors(i,j) /= var.sqrt_diagonal_mass(i);
858 else if (var.UseCholeskyFactoForMass())
861 for (
int j = 0; j < eigen_vectors.GetN(); j++)
863 for (
int i = 0; i < eigen_vectors.GetM(); i++)
864 Xcol(i) = eigen_vectors(i,j);
866 var.SolveCholeskyMass(SeldonTrans, Xcol);
867 for (
int i = 0; i < eigen_vectors.GetM(); i++)
868 eigen_vectors(i,j) = Xcol(i);
872 if (var.GetComputationalMode() != var.REGULAR_MODE)
874 if ( (var.eigenvalue_computation_mode == var.INVERT_MODE)
875 && (var.GetTypeSpectrum() != var.CENTERED_EIGENVALUES))
879 else if ((var.DiagonalMass())|| (var.UseCholeskyFactoForMass())
880 || (var.eigenvalue_computation_mode == var.INVERT_MODE))
883 for (
int i = 0; i < eigen_values.GetM(); i++)
885 if ((eigen_values(i) == 0) && (lambda_imag(i) == 0))
892 complex<T0> val = 1.0/complex<T0>(eigen_values(i), lambda_imag(i))
893 + complex<T0>(shiftr, shifti);
895 eigen_values(i) = real(val);
896 lambda_imag(i) = imag(val);
901 else if (var.GetImagShiftValue() != T0(0))
903 int n = eigen_vectors.GetM();
908 while (j < eigen_values.GetM())
910 if (lambda_imag(j) == T0(0))
914 for (
int i = 0; i < eigen_vectors.GetM(); i++)
915 X(i) = eigen_vectors(i,j);
918 var.MltStiffness(X, Ax);
919 eigen_values(j) = DotProd(X, Ax)/DotProd(X, Mx);
926 if (j == eigen_values.GetM() - 1)
928 eigen_values(j) = 0.0;
929 lambda_imag(j) = 0.0;
935 for (
int i = 0; i < eigen_vectors.GetM(); i++)
937 X(i) = eigen_vectors(i, j);
938 Y(i) = eigen_vectors(i, j+1);
942 var.MltStiffness(X, Ax);
943 T0 numr = DotProd(X, Ax);
944 T0 numi = DotProd(Y, Ax);
946 var.MltStiffness(Y, Ax);
947 numr += DotProd(Y, Ax);
948 numi -= DotProd(X, Ax);
951 T0 denr = DotProd(X, Mx);
952 T0 deni = DotProd(Y, Mx);
955 denr += DotProd(Y, Mx);
956 deni -= DotProd(X, Mx);
958 complex<T0> val = complex<T0>(numr, numi)/complex<T0>(denr, deni);
960 eigen_values(j) = real(val);
961 eigen_values(j+1) = real(val);
963 lambda_imag(j) = -imag(val);
964 lambda_imag(j+1) = imag(val);
982 template<
class EigenPb,
class Vector1,
class Matrix1,
class T0>
984 Matrix1& eigen_vectors,
985 const complex<T0>& shiftr,
const complex<T0>& shifti)
988 if (var.DiagonalMass())
991 for (
int i = 0; i < var.sqrt_diagonal_mass.GetM(); i++)
992 for (
int j = 0; j < eigen_vectors.GetN(); j++)
993 eigen_vectors(i,j) /= var.sqrt_diagonal_mass(i);
995 else if (var.UseCholeskyFactoForMass())
998 for (
int j = 0; j < eigen_vectors.GetN(); j++)
1000 for (
int i = 0; i < eigen_vectors.GetM(); i++)
1001 Xcol(i) = eigen_vectors(i,j);
1003 var.SolveCholeskyMass(SeldonTrans, Xcol);
1004 for (
int i = 0; i < eigen_vectors.GetM(); i++)
1005 eigen_vectors(i,j) = Xcol(i);
1009 if (var.GetComputationalMode() != var.REGULAR_MODE)
1011 if ( (var.eigenvalue_computation_mode == var.INVERT_MODE)
1012 && (var.GetTypeSpectrum() != var.CENTERED_EIGENVALUES))
1016 else if ((var.DiagonalMass())|| (var.UseCholeskyFactoForMass())
1017 || (var.eigenvalue_computation_mode == var.INVERT_MODE))
1020 for (
int i = 0; i < eigen_values.GetM(); i++)
1022 complex<T0> val = 1.0/eigen_values(i) + shiftr;
1024 eigen_values(i) = val;
1038 template<
class T,
class Storage1,
class Storage2,
1039 class Alloc1,
class Alloc2>
1043 int type_spectrum,
int type_sort,
1044 const T& shift_r,
const T& shift_i)
1046 int n = min(lambda_r.GetM(), eigen_old.GetN());;
1048 IVect permutation(n);
1050 eigen_new.Reallocate(eigen_old.GetM(), n);
1061 for (
int i = 0; i < n; i++)
1062 L(i) = 1.0/abs(shift_r - lambda_r(i));
1067 for (
int i = 0; i < n; i++)
1068 L(i) = 1.0/abs(shift_i - lambda_i(i));
1073 for (
int i = 0; i < n; i++)
1074 L(i) = 1.0/abs(complex<T>(shift_r - lambda_r(i), shift_i - lambda_i(i)));
1086 for (
int i = 0; i < n; i++)
1087 L(i) = abs(lambda_r(i));
1092 for (
int i = 0; i < n; i++)
1093 L(i) = abs(lambda_i(i));
1098 for (
int i = 0; i < n; i++)
1099 L(i) = abs(complex<T>(lambda_r(i), lambda_i(i)));
1106 Sort(L, permutation);
1109 Vector<T> oldLambda_r = lambda_r, oldLambda_i = lambda_i;
1110 for (
int i = 0; i < n; i++)
1112 lambda_r(i) = oldLambda_r(permutation(i));
1113 lambda_i(i) = oldLambda_i(permutation(i));
1114 for (
int j = 0; j < eigen_old.GetM(); j++)
1115 eigen_new(j, i) = eigen_old(j, permutation(i));
1122 template<
class T,
class Storage1,
class Storage2,
1123 class Alloc1,
class Alloc2>
1127 int type_spectrum,
int type_sort,
1128 const complex<T>& shift_r,
const complex<T>& shift_i)
1131 int n = min(lambda_r.GetM(), eigen_old.GetN());;
1133 IVect permutation(n);
1135 eigen_new.Reallocate(eigen_old.GetM(), n);
1146 for (
int i = 0; i < n; i++)
1147 L(i) = 1.0/abs(real(shift_r - lambda_r(i)));
1152 for (
int i = 0; i < n; i++)
1153 L(i) = 1.0/abs(imag(shift_r - lambda_r(i)));
1158 for (
int i = 0; i < n; i++)
1159 L(i) = 1.0/abs(shift_r - lambda_r(i));
1171 for (
int i = 0; i < n; i++)
1172 L(i) = abs(real(lambda_r(i)));
1177 for (
int i = 0; i < n; i++)
1178 L(i) = abs(imag(lambda_r(i)));
1183 for (
int i = 0; i < n; i++)
1184 L(i) = abs(lambda_r(i));
1191 Sort(L, permutation);
1195 for (
int i = 0; i < n; i++)
1197 lambda_r(i) = oldLambda_r(permutation(i));
1198 lambda_i(i) = oldLambda_i(permutation(i));
1199 for (
int j = 0; j < eigen_old.GetM(); j++)
1200 eigen_new(j, i) = eigen_old(j, permutation(i));
1212 template<
class T,
class Prop,
class Storage,
1213 class Tmass,
class PropM,
class StorageM>
1216 Matrix<Tmass, PropM, StorageM> >()
1222 template<
class T,
class Prop,
class Storage,
1223 class Tmass,
class PropM,
class StorageM>
1227 if (this->Mh == NULL)
1229 mat_chol.Reallocate(this->n_, this->n_);
1230 mat_chol.SetIdentity();
1234 mat_chol = *(this->Mh);
1235 GetCholesky(mat_chol);
1236 Xchol_real.Reallocate(mat_chol.GetM());
1237 Xchol_imag.Reallocate(mat_chol.GetM());
1243 template<
class T,
class Prop,
class Storage,
1244 class Tmass,
class PropM,
class StorageM>
1245 template<
class TransStatus,
class T0>
1249 MltCholesky(transA, mat_chol, X);
1254 template<
class T,
class Prop,
class Storage,
1255 class Tmass,
class PropM,
class StorageM>
1256 template<
class TransStatus,
class T0>
1260 SolveCholesky(transA, mat_chol, X);
1265 template<
class T,
class Prop,
class Storage,
1266 class Tmass,
class PropM,
class StorageM>
1267 template<
class TransStatus>
1271 for (
int i = 0; i < X.GetM(); i++)
1273 Xchol_real(i) = real(X(i));
1274 Xchol_imag(i) = imag(X(i));
1277 MltCholesky(transA, mat_chol, Xchol_real);
1278 MltCholesky(transA, mat_chol, Xchol_imag);
1280 for (
int i = 0; i < X.GetM(); i++)
1281 X(i) = complex<double>(Xchol_real(i), Xchol_imag(i));
1286 template<
class T,
class Prop,
class Storage,
1287 class Tmass,
class PropM,
class StorageM>
1288 template<
class TransStatus>
1292 for (
int i = 0; i < X.GetM(); i++)
1294 Xchol_real(i) = real(X(i));
1295 Xchol_imag(i) = imag(X(i));
1298 SolveCholesky(transA, mat_chol, Xchol_real);
1299 SolveCholesky(transA, mat_chol, Xchol_imag);
1301 for (
int i = 0; i < X.GetM(); i++)
1302 X(i) = complex<double>(Xchol_real(i), Xchol_imag(i));
1307 template<
class T,
class Prop,
class Storage,
1308 class Tmass,
class PropM,
class StorageM>
1312 if (this->Kh == NULL)
1313 this->PrintErrorInit();
1315 this->complex_system =
false;
1317 mat_lu = *(this->Kh);
1319 if (this->Mh == NULL)
1321 for (
int i = 0; i < this->n_; i++)
1325 Add(a, *(this->Mh), mat_lu);
1328 GetLU(mat_lu, pivot);
1333 template<
class T,
class Prop,
class Storage,
1334 class Tmass,
class PropM,
class StorageM>
1339 ComputeAndFactorizeComplexMatrix(a, b);
1344 template<
class T,
class Prop,
class Storage,
1345 class Tmass,
class PropM,
class StorageM>
1350 if (this->Kh == NULL)
1351 this->PrintErrorInit();
1353 this->complex_system =
true;
1356 for (
int i = 0; i < this->n_; i++)
1357 for (
int j = 0; j < this->n_; j++)
1358 InvMat(i, j) = (*this->Kh)(i, j);
1361 if (this->Mh == NULL)
1363 for (
int i = 0; i < this->n_; i++)
1368 for (
int i = 0; i < this->n_; i++)
1369 for (
int j = 0; j < this->n_; j++)
1370 InvMat(i, j) += a * (*this->Mh)(i, j);
1377 mat_lu.Reallocate(this->n_, this->n_);
1380 for (
int i = 0; i < this->n_; i++)
1381 for (
int j = 0; j < this->n_; j++)
1382 mat_lu(i, j) = real(InvMat(i, j));
1386 for (
int i = 0; i < this->n_; i++)
1387 for (
int j = 0; j < this->n_; j++)
1388 mat_lu(i, j) = imag(InvMat(i, j));
1394 template<
class T,
class Prop,
class Storage,
1395 class Tmass,
class PropM,
class StorageM>
template<
class T0>
1398 const complex<T0>& b,
bool real_p)
1401 cout <<
"Case not handled" << endl;
1407 template<
class T,
class Prop,
class Storage,
1408 class Tmass,
class PropM,
class StorageM>
template<
class T0>
1412 if (this->complex_system)
1417 SolveLU(mat_lu, pivot, Y);
1423 template<
class T,
class Prop,
class Storage,
1424 class Tmass,
class PropM,
class StorageM>
1425 template<
class TransA,
class T0>
1429 if (this->complex_system)
1430 Mlt(transA, mat_lu, X, Y);
1434 SolveLU(transA, mat_lu, pivot, Y);
1440 template<
class T,
class Prop,
class Storage,
1441 class Tmass,
class PropM,
class StorageM>
1459 template<
class T,
class MatStiff,
class MatMass>
1471 template<
class T,
class MatStiff,
class MatMass>
1474 chol_facto_mass_matrix.SelectDirectSolver(type);
1479 template<
class T,
class MatStiff,
class MatMass>
1483 if (this->Mh == NULL)
1484 this->PrintErrorInit();
1486 if (this->print_level > 0)
1487 chol_facto_mass_matrix.ShowMessages();
1490 FactorizeCholeskyMass(x_test, *this->Mh);
1492 if (this->print_level < 2)
1493 chol_facto_mass_matrix.HideMessages();
1495 Xchol_real.Reallocate(this->n_);
1496 Xchol_imag.Reallocate(this->n_);
1501 template<
class T,
class MatStiff,
class MatMass>
1502 template<
class Storage,
class Alloc>
1506 chol_facto_mass_matrix.Factorize(M,
true);
1511 template<
class T,
class MatStiff,
class MatMass>
1512 template<
class T0,
class T1,
class Prop,
class Storage,
class Alloc>
1516 cout <<
"Cholesky factorisation has not been implemented "
1517 <<
"for complex matrices" << endl;
1523 template<
class T,
class MatStiff,
class MatMass>
1524 template<
class TransStatus,
class T0>
1528 chol_facto_mass_matrix.Mlt(TransA, X);
1533 template<
class T,
class MatStiff,
class MatMass>
1534 template<
class TransStatus,
class T0>
1538 chol_facto_mass_matrix.Solve(TransA, X);
1543 template<
class T,
class MatStiff,
class MatMass>
1544 template<
class TransStatus>
1549 MltCholeskyMass(TransA, X, x_test);
1554 template<
class T,
class MatStiff,
class MatMass>
1555 template<
class TransStatus>
1560 cout <<
"Cholesky factorisation has not been implemented "
1561 <<
"for complex matrices" << endl;
1567 template<
class T,
class MatStiff,
class MatMass>
1568 template<
class TransStatus>
1572 for (
int i = 0; i < X.GetM(); i++)
1574 Xchol_real(i) = real(X(i));
1575 Xchol_imag(i) = imag(X(i));
1578 chol_facto_mass_matrix.Mlt(TransA, Xchol_real);
1579 chol_facto_mass_matrix.Mlt(TransA, Xchol_imag);
1581 for (
int i = 0; i < X.GetM(); i++)
1582 X(i) = complex<double>(Xchol_real(i), Xchol_imag(i));
1588 template<
class T,
class MatStiff,
class MatMass>
1589 template<
class TransStatus>
1594 SolveCholeskyMass(TransA, X, x_test);
1599 template<
class T,
class MatStiff,
class MatMass>
1600 template<
class TransStatus>
1605 cout <<
"Cholesky factorisation has not been "
1606 <<
"implemented for complex matrices" << endl;
1612 template<
class T,
class MatStiff,
class MatMass>
1613 template<
class TransStatus>
1617 for (
int i = 0; i < X.GetM(); i++)
1619 Xchol_real(i) = real(X(i));
1620 Xchol_imag(i) = imag(X(i));
1623 chol_facto_mass_matrix.Solve(TransA, Xchol_real);
1624 chol_facto_mass_matrix.Solve(TransA, Xchol_imag);
1626 for (
int i = 0; i < X.GetM(); i++)
1627 X(i) = complex<double>(Xchol_real(i), Xchol_imag(i));
1633 template<
class T,
class MatStiff,
class MatMass>
1637 this->complex_system =
false;
1638 if (this->Kh == NULL)
1639 this->PrintErrorInit();
1641 if (this->print_level > 0)
1642 mat_lu.ShowMessages();
1646 if (this->Mh != NULL)
1652 T zero; SetComplexZero(zero);
1660 if (this->Mh == NULL)
1662 A.Reallocate(this->n_, this->n_);
1666 Copy(*(this->Mh), A);
1669 mat_lu.Factorize(A);
1674 Copy(*(this->Mh), A);
1676 mat_lu.Factorize(A);
1683 Copy(*(this->Kh), A);
1687 if (this->Mh == NULL)
1689 for (
int i = 0; i < this->n_; i++)
1690 A.AddInteraction(i, i, a);
1693 Add(a, *(this->Mh), A);
1696 mat_lu.Factorize(A);
1702 Copy(*(this->Kh), A);
1706 if (this->Mh == NULL)
1708 for (
int i = 0; i < this->n_; i++)
1709 A.AddInteraction(i, i, a);
1712 Add(a, *(this->Mh), A);
1715 mat_lu.Factorize(A);
1718 if (this->print_level < 2)
1719 mat_lu.HideMessages();
1724 template<
class T,
class MatStiff,
class MatMass>
1727 const complex<T>& b,
1730 ComputeAndFactorizeComplexMatrix(a, b, real_p);
1735 template<
class T,
class MatStiff,
class MatMass>
template<
class T0>
1738 const complex<T0>& b,
1742 cout <<
"Case not handled" << endl;
1748 template<
class T,
class MatStiff,
class MatMass>
1751 const complex<double>& b,
1754 this->complex_system =
true;
1755 if (this->Kh == NULL)
1756 this->PrintErrorInit();
1758 imag_solution = !real_p;
1760 if (this->print_level > 0)
1761 mat_lu_cplx.ShowMessages();
1765 if (this->Mh != NULL)
1771 complex<double> zero(0, 0);
1779 if (this->Mh == NULL)
1781 A.Reallocate(this->n_, this->n_);
1785 Copy(*(this->Mh), A);
1788 mat_lu_cplx.Factorize(A);
1793 Copy(*(this->Mh), A);
1795 mat_lu_cplx.Factorize(A);
1802 Copy(*(this->Kh), A);
1806 if (this->Mh == NULL)
1808 for (
int i = 0; i < this->n_; i++)
1809 A.AddInteraction(i, i, a);
1812 Add(a, *(this->Mh), A);
1815 mat_lu_cplx.Factorize(A);
1821 Copy(*(this->Kh), A);
1825 if (this->Mh == NULL)
1827 for (
int i = 0; i < this->n_; i++)
1828 A.AddInteraction(i, i, a);
1831 Add(a, *(this->Mh), A);
1834 mat_lu_cplx.Factorize(A);
1837 if (this->print_level < 2)
1838 mat_lu_cplx.HideMessages();
1843 template<
class T,
class MatStiff,
class MatMass>
template<
class T0>
1847 if (this->complex_system)
1849 ComputeComplexSolution(SeldonNoTrans, X, Y);
1860 template<
class T,
class MatStiff,
class MatMass>
1861 template<
class TransA,
class T0>
1865 if (this->complex_system)
1867 ComputeComplexSolution(transA, X, Y);
1872 mat_lu.Solve(transA, Y);
1878 template<
class T,
class MatStiff,
class MatMass>
template<
class TransA>
1884 for (
int i = 0; i < this->n_; i++)
1887 mat_lu_cplx.Solve(Xcplx);
1890 for (
int i = 0; i < this->n_; i++)
1891 Y(i) = imag(Xcplx(i));
1893 for (
int i = 0; i < this->n_; i++)
1894 Y(i) = real(Xcplx(i));
1900 template<
class T,
class MatStiff,
class MatMass>
template<
class TransA>
1903 const Vector<complex<double> >& X,
1904 Vector<complex<double> >& Y)
1907 mat_lu_cplx.Solve(transA, Y);
1912 template<
class T,
class MatStiff,
class MatMass>
1916 mat_lu_cplx.Clear();
1917 chol_facto_mass_matrix.Clear();
1924 template<
class T,
class MatStiff>
1931 #ifndef SELDON_WITH_COMPILED_LIBRARY
1932 int TypeEigenvalueSolver::default_solver(0);
1938 #ifdef SELDON_WITH_ANASAZI
1942 #ifdef SELDON_WITH_FEAST
1946 #ifdef SELDON_WITH_ARPACK
1954 template<
class EigenPb,
class Vector1,
class Vector2,
1955 class T,
class Prop,
class Storage,
class Alloc3>
1956 void GetEigenvaluesEigenvectors(EigenPb& var_eig, Vector1& lambda,
1960 int type_solver = TypeEigenvalueSolver::default_solver;
1961 if (type_solver == TypeEigenvalueSolver::DEFAULT)
1964 if (type_solver == TypeEigenvalueSolver::ARPACK)
1966 #ifdef SELDON_WITH_ARPACK
1967 T zero; SetComplexZero(zero);
1973 eigen_vec, var_eig.LARGE_EIGENVALUES,
1974 var_eig.GetTypeSorting(), zero, zero);
1976 cout <<
"Recompile with Arpack" << endl;
1980 else if (type_solver == TypeEigenvalueSolver::ANASAZI)
1982 #ifdef SELDON_WITH_ANASAZI
1983 T zero; SetComplexZero(zero);
1984 Matrix<T, General, ColMajor> eigen_old;
1989 eigen_vec, var_eig.LARGE_EIGENVALUES,
1990 var_eig.GetTypeSorting(), zero, zero);
1992 cout <<
"Recompile with Anasazi" << endl;
1996 else if (type_solver == TypeEigenvalueSolver::FEAST)
1998 #ifdef SELDON_WITH_FEAST
1999 T zero; SetComplexZero(zero);
2000 Matrix<T, General, ColMajor> eigen_old;
2001 FindEigenvaluesFeast(var_eig, lambda, lambda_imag, eigen_old);
2005 eigen_vec, var_eig.LARGE_EIGENVALUES,
2006 var_eig.GetTypeSorting(), zero, zero);
2008 cout <<
"Recompile with MKL" << endl;
2014 cout <<
"Recompile with eigenvalue solver" << endl;
2022 #define SELDON_FILE_EIGENVALUE_SOLVER_CXX