VirtualEigenvalueSolver.cxx
1 #ifndef SELDON_FILE_VIRTUAL_EIGENVALUE_SOLVER_CXX
2 
3 #include "VirtualEigenvalueSolver.hxx"
4 
5 #ifdef SELDON_WITH_SLEPC
6 #include <slepceps.h>
7 #endif
8 
9 namespace Seldon
10 {
11 
12  /****************
13  * AnasaziParam *
14  ****************/
15 
16 
19  {
20  type_solver = SOLVER_LOBPCG;
21  ortho_manager = ORTHO_DGKS;
22  nb_blocks = 2;
23  restart_number = 20;
24  }
25 
26 
29  {
30  return nb_blocks;
31  }
32 
33 
36  {
37  nb_blocks = n;
38  }
39 
40 
43  {
44  return restart_number;
45  }
46 
47 
50  {
51  restart_number = m;
52  }
53 
54 
57  {
58  return ortho_manager;
59  }
60 
61 
64  {
65  return type_solver;
66  }
67 
68 
71  {
72  type_solver = type;
73  }
74 
75 
76  /****************
77  * SlepcParam *
78  ****************/
79 
80 
83  {
84  type_solver = KRYLOVSCHUR;
85  block_size = -1; nstep = -1;
86  type_extraction = -1; quadrature_rule = -1;
87  nstep_inner = -1; nstep_outer = -1;
88  npoints = -1;
89  moment_size = -1; block_max_size = -1; npart = 1;
90  delta_rank = 0.0; delta_spur = 0.0;
91  borth = -1; double_exp = -1;
92  init_size = -1;
93  krylov_restart = -1; restart_number = -1; restart_add = -1;
94  nb_conv_vector = -1; nb_conv_vector_proj = -1;
95  non_locking_variant = false;
96  restart_ratio = -1.0;
97  }
98 
99 
100  // definition available in Slepc.cxx if Slepc is enabled
101 #ifndef SELDON_WITH_SLEPC
102  const char* SlepcParam::GetEigensolverChar() const
103  {
104  return "";
105  }
106 #endif
107 
108 
109  /**************
110  * FeastParam *
111  **************/
112 
115  {
116  evaluate_number_eigenval = false;
118  type_integration = -1;
119  emin_interval = 0.0;
120  emax_interval = 0.0;
121 
122  center_spectrum = complex<double>(0, 0);
123  radius_spectrum = 0.0;
124 
125  }
126 
129  {
130  return emin_interval;
131  }
132 
133 
136  {
137  return emax_interval;
138  }
139 
140 
142  void FeastParam::SetIntervalSpectrum(double l0, double l1)
143  {
144  emin_interval = l0;
145  emax_interval = l1;
146  }
147 
148 
150  void FeastParam::SetCircleSpectrum(const complex<double>& z, double r)
151  {
152  center_spectrum = z; radius_spectrum = r;
153  ratio_ellipse = 100; angle_ellipse = 0;
154  }
155 
156 
158  void FeastParam::SetEllipseSpectrum(const complex<double>& z, double r,
159  double ratio, double teta)
160  {
161  center_spectrum = z; radius_spectrum = r;
162  ratio_ellipse = ratio; angle_ellipse = teta;
163  }
164 
165 
166  /****************************
167  * GeneralEigenProblem_Base *
168  ****************************/
169 
170 
173  {
175  nb_arnoldi_vectors = 0;
177 
178  // default => we want largest eigenvalues by magnitude
179  type_spectrum_wanted = LARGE_EIGENVALUES;
180  type_sort_eigenvalues = SORTED_MODULUS;
181 
182  stopping_criterion = 1e-6;
183  nb_maximum_iterations = 1000;
184  nb_linear_solves = 0;
185  display_every = 100000;
186  print_level = 0;
187 
188  nb_prod = 0;
189  n_ = 0; nglob = 0;
190 
191 #ifdef SELDON_WITH_MPI
192  // for parallel execution, default communicator : all the processors
193  comm = MPI_COMM_WORLD;
194  rci_comm = MPI_COMM_WORLD;
195  comm_global = MPI_COMM_WORLD;
196  global_comm_set = false;
197 #endif
198  }
199 
200 
203  {
204  }
205 
206 
207 #ifdef SELDON_WITH_MPI
208  void GeneralEigenProblem_Base::SetCommunicator(const MPI_Comm& comm_)
210  {
211  comm = comm_;
212 
213  // if global communicator has been set, we can construct
214  // the rci_comm (L2_comm in feast)
215  if (global_comm_set)
216  {
217  int key = 0; MPI_Comm_rank(comm_global, &key);
218  int solver_rank = 0; MPI_Comm_rank(comm, &solver_rank);
219  MPI_Comm_split(comm_global, solver_rank, key, &rci_comm);
220  }
221  else
222  rci_comm = MPI_COMM_SELF;
223  }
224 
225 
227  MPI_Comm& GeneralEigenProblem_Base::GetCommunicator()
228  {
229  return comm;
230  }
231 
233  MPI_Comm& GeneralEigenProblem_Base::GetRciCommunicator()
234  {
235  return rci_comm;
236  }
237 
239  void GeneralEigenProblem_Base::SetGlobalCommunicator(const MPI_Comm& comm_)
240  {
241  comm_global = comm_;
242  global_comm_set = true;
243  }
244 
246  MPI_Comm& GeneralEigenProblem_Base::GetGlobalCommunicator()
247  {
248  return comm_global;
249  }
250 #endif
251 
252 
255  {
256 #ifdef SELDON_WITH_MPI
257  int rank_proc;
258  MPI_Comm_rank(comm, &rank_proc);
259  return rank_proc;
260 #endif
261 
262  return 0;
263  }
264 
265 
268  {
269 #ifdef SELDON_WITH_MPI
270  int rank_proc;
271  MPI_Comm_rank(comm_global, &rank_proc);
272  return rank_proc;
273 #endif
274 
275  return 0;
276  }
277 
278 
281  {
282  return nb_eigenvalues_wanted;
283  }
284 
285 
288  {
290  }
291 
292 
295  {
296  return type_spectrum_wanted;
297  }
298 
299 
302  {
303  return type_sort_eigenvalues;
304  }
305 
306 
309  {
310  stopping_criterion = eps;
311  }
312 
313 
316  {
317  return stopping_criterion;
318  }
319 
320 
323  {
325  }
326 
327 
330  {
331  return nb_maximum_iterations;
332  }
333 
334 
338  {
339  return nb_prod;
340  }
341 
342 
345  {
346  return nb_arnoldi_vectors;
347  }
348 
349 
352  {
354  nb_arnoldi_vectors = n;
355  }
356 
357 
360  {
361  return n_;
362  }
363 
364 
367  {
368  return nglob;
369  }
370 
371 
374  {
375  return n_;
376  }
377 
378 
381  {
382  return print_level;
383  }
384 
385 
388  {
389  print_level = lvl;
390  display_every = 1000000;
391  if (lvl == 1)
392  display_every = 1000;
393  else if (lvl == 2)
394  display_every = 100;
395  else if (lvl >= 3)
396  display_every = 10;
397  }
398 
399 
402  {
403  nb_prod++;
404  }
405 
406 
409  {
410  return nb_linear_solves;
411  }
412 
413 
416  {
418 
419 #ifdef SELDON_WITH_MPI
420  int rank; MPI_Comm_rank(comm_global, &rank);
421 #else
422  int rank(0);
423 #endif
424 
425  if (print_level >= 1)
426  {
427  if (nb_linear_solves%display_every == 0)
428  if (rank == 0)
429  cout<<" Iteration number " << nb_linear_solves << endl;
430  }
431  }
432 
435  {
436  n_ = n;
437  nb_prod = 0;
438  nb_linear_solves = 0;
439 
440  // counting the size of the global system for parallel computation
441  nglob = n;
442 
443 #ifdef SELDON_WITH_MPI
444  MPI_Allreduce(&n, &nglob, 1, MPI_INTEGER, MPI_SUM, comm);
445 #endif
446 
447  /*if (nb_eigenvalues_wanted >= (nglob - 2))
448  {
449  cout << "Too many wanted eigenvalues " << endl;
450  cout << nb_eigenvalues_wanted <<
451  " asked eigenvalues, but the rank of the matrix is lower than "
452  << n_ << endl;
453 
454  abort();
455  } */
456 
458  nb_arnoldi_vectors = min(nglob, 2*nb_eigenvalues_wanted+2);
459  }
460 
461 
462  /***********************
463  * GeneralEigenProblem *
464  ***********************/
465 
466 
468  template<class T>
470  {
471  compar_eigenval = NULL;
472  SetComplexZero(shift); SetComplexZero(shift_imag);
473  }
474 
475 
477 
482  template<class T>
484  {
485  return shift;
486  }
487 
488 
490 
496  template<class T>
498  {
499  return shift_imag;
500  }
501 
502 
504  template<class T>
506  {
507  shift = val;
508  }
509 
510 
512  template<class T>
514  {
515  shift_imag = val;
516  }
517 
518 
520  template<class T>
522  ::GetComplexShift(const Treal& sr, const Treal& si, Tcplx& s) const
523  {
524  s = complex<Treal>(sr, si);
525  }
526 
527 
529  template<class T>
531  ::GetComplexShift(const Tcplx& sr, const Tcplx& si, Tcplx& s) const
532  {
533  s = sr;
534  }
535 
536 
538 
542  template<class T>
544  ::SetTypeSpectrum(int type, const T& val, int type_sort)
545  {
546  this->type_spectrum_wanted = type;
547  this->shift = val;
548  this->type_sort_eigenvalues = type_sort;
549  }
550 
551 
553 
557  template<class T>
559  ::SetTypeSpectrum(int type, const complex<T>& val, int type_sort)
560  {
561  // for real unsymmetric eigenproblems, you can
562  // specify a complex shift
563  this->type_spectrum_wanted = type;
564  shift = real(val);
565  shift_imag = imag(val);
566 
567  this->type_sort_eigenvalues = type_sort;
568  }
569 
570 
572  template<class T>
574  {
575  compar_eigenval = ev;
576  }
577 
578 #ifdef SELDON_WITH_SLEPC
579  template<class T> template<class T0>
580  PetscErrorCode GeneralEigenProblem<T>::
581  GetComparisonEigenvalueSlepcGen(PetscScalar, PetscScalar, PetscScalar, PetscScalar, T0,
582  PetscInt*, void*)
583  {
584  cout << "Incompatibles types between T and PetscScalar" << endl;
585  abort();
586  return 0;
587  }
588 
589 
591  template<class T>
592  PetscErrorCode GeneralEigenProblem<T>::
593  GetComparisonEigenvalueSlepcGen(PetscScalar Lr, PetscScalar Li, PetscScalar Lr2, PetscScalar Li2, PetscScalar,
594  PetscInt* res, void* ctx)
595  {
596  // we call the method CompareEigenvalue in the object compar_eigenval
597  GeneralEigenProblem<T>& var = *reinterpret_cast<GeneralEigenProblem<T>* >(ctx);
598  if (var.compar_eigenval == NULL)
599  {
600  cout << "Invalid pointer for compar_eigenval" << endl;
601  abort();
602  }
603 
604  T Lr_, Li_, Lr2_, Li2_;
605  to_complex_eigen(Lr, Lr_); to_complex_eigen(Li, Li_);
606  to_complex_eigen(Lr2, Lr2_); to_complex_eigen(Li2, Li2_);
607  int y = var.compar_eigenval->CompareEigenvalue(Lr_, Li_, Lr2_, Li2_);
608  *res = y;
609  return 0;
610  }
611 
612 
614  template<class T>
615  PetscErrorCode GeneralEigenProblem<T>::
616  GetComparisonEigenvalueSlepc(PetscScalar Lr, PetscScalar Li, PetscScalar Lr2, PetscScalar Li2,
617  PetscInt* res, void* ctx)
618  {
619  T z; SetComplexZero(z);
620  GetComparisonEigenvalueSlepcGen(Lr, Li, Lr2, Li2, z, res, ctx);
621  return 0;
622  }
623 #endif
624 
625 
627 
631  template<>
632  void GeneralEigenProblem<double>
633  ::FillComplexEigenvectors(int m, const complex<double>& Emid, double eps,
634  const Vector<complex<double> >& lambda_cplx,
635  const Matrix<complex<double>, General, ColMajor>& Ecplx,
638  {
639  // if imag_pos is true, we will select only eigenvalues with Im(lambda) >= 0
640  // if imag_pos is false, we will select only eigenvalues with Im(lambda) <= 0
641  bool imag_pos = true;
642  if (imag(Emid) < 0)
643  imag_pos = false;
644 
645  // type_eigenval : 0 for real, 1 for complex, -1 to be dropped
646  // some eigenvalues are dropped because by construction eigenvalues are complex conjugate
647  Vector<int> type_eigenval(m);
648  type_eigenval.Fill(-1);
649  int nb_val = 0;
650  for (int i = 0; i < m; i++)
651  {
652  if (abs(imag(lambda_cplx(i))) <= eps)
653  {
654  type_eigenval(i) = 0;
655  nb_val++;
656  }
657  else
658  {
659  if (imag_pos)
660  {
661  if (imag(lambda_cplx(i)) > 0)
662  {
663  type_eigenval(i) = 1;
664  nb_val += 2;
665  }
666  }
667  else
668  {
669  if (imag(lambda_cplx(i)) < 0)
670  {
671  type_eigenval(i) = 1;
672  nb_val += 2;
673  }
674  }
675  }
676  }
677 
678  // we fill output arrays Lr, Li and E
679  int N = Ecplx.GetM();
680  Lr.Reallocate(nb_val);
681  Li.Reallocate(nb_val);
682  E.Reallocate(N, nb_val);
683  nb_val = 0;
684  for (int i = 0; i < m; i++)
685  {
686  if (type_eigenval(i) == 0)
687  {
688  Lr(nb_val) = realpart(lambda_cplx(i));
689  Li(nb_val) = 0.0;
690  for (int j = 0; j < N; j++)
691  E(j, nb_val) = realpart(Ecplx(j, i));
692 
693  nb_val++;
694  }
695  else if (type_eigenval(i) == 1)
696  {
697  Lr(nb_val) = real(lambda_cplx(i));
698  Li(nb_val) = imag(lambda_cplx(i));
699  Lr(nb_val+1) = Lr(nb_val);
700  Li(nb_val+1) = -Li(nb_val);
701  for (int j = 0; j < N; j++)
702  {
703  E(j, nb_val) = real(Ecplx(j, i));
704  E(j, nb_val+1) = imag(Ecplx(j, i));
705  }
706 
707  nb_val += 2;
708  }
709  }
710  }
711 
712 
714  template<>
716  ::FillComplexEigenvectors(int m, const complex<double>& Emid, double eps,
717  const Vector<complex<double> >& lambda_cplx,
718  const Matrix<complex<double>, General, ColMajor>& Ecplx,
719  Vector<complex<double> >& Lr, Vector<complex<double> >& Li,
720  Matrix<complex<double>, General, ColMajor>& E)
721  {
722  // we fill output arrays Lr and E
723  int N = Ecplx.GetM();
724  Lr.Reallocate(m);
725  E.Reallocate(N, m);
726  for (int i = 0; i < m; i++)
727  {
728  Lr(i) = lambda_cplx(i);
729  for (int j = 0; j < N; j++)
730  E(j, i) = Ecplx(j, i);
731  }
732  }
733 
734 
736  template<class T>
738  {
739  }
740 
741 
742 #ifdef SELDON_WITH_MPI
743  template<class T>
746  ::AssembleEigenvectors(Matrix<T, General, ColMajor>& eigen_vec, const Vector<int>& local_col_numbers,
747  Vector<int>* ProcSharingRows, Vector<Vector<int> >* SharingRowNumbers,
748  int nloc, int nodl_scalar_, int nb_unknowns_scal_)
749  {
750  int nvec = eigen_vec.GetN();
751  eigen_vec.Resize(nloc, nvec);
752 
753  Vector<T> X(nloc);
754  for (int j = 0; j < nvec; j++)
755  {
756  X.Zero();
757  for (int i = 0; i < this->n_; i++)
758  X(local_col_numbers(i)) = eigen_vec(i, j);
759 
760  AssembleVector(X, MPI_SUM, *ProcSharingRows, *SharingRowNumbers,
761  this->comm, nodl_scalar_, nb_unknowns_scal_, 17);
762 
763  for (int i = 0; i < nloc; i++)
764  eigen_vec(i, j) = X(i);
765  }
766  }
767 #endif
768 
769  /*********************
770  * EigenProblem_Base *
771  *********************/
772 
773 
775  template<class T>
777  {
778  eigenvalue_computation_mode = 1;
779  nb_add_eigenvalues = 0;
780 
781  use_cholesky = false;
782  diagonal_mass = false;
783 
784  complex_system = false;
785  selected_part = COMPLEX_PART;
786  }
787 
788 
790  template<class T>
792  {
793  return eigenvalue_computation_mode;
794  }
795 
796 
798  template<class T>
800  {
801  eigenvalue_computation_mode = mode;
802  }
803 
804 
806  template<class T>
808  {
809  return nb_add_eigenvalues;
810  }
811 
813  template<class T>
815  {
816  nb_add_eigenvalues = n;
817  }
818 
819 
821  template<class T>
823  {
824  return anasazi_param;
825  }
826 
827 
829  template<class T>
831  {
832  return slepc_param;
833  }
834 
835 
837  template<class T>
839  {
840  return feast_param;
841  }
842 
843 
846  template<class T>
848  {
849  use_cholesky = chol;
850  }
851 
852 
854  template<class T>
856  {
857  return use_cholesky;
858  }
859 
860 
862  template<class T>
864  {
865  diagonal_mass = diag;
866  }
867 
868 
870  template<class T>
872  {
873  return diagonal_mass;
874  }
875 
876 
878  template<class T>
880  {
881  cout << "InitMatrix has not been called" << endl;
882  abort();
883  }
884 
885 
887  template<class T>
889  {
890  // nothing to do, we consider that mass matrix
891  // is already computed
892  }
893 
894 
896  template<class T>
898  {
899  // mass matrix already computed in Mh
900  }
901 
902 
904  template<class T>
906  {
907  // nothing to do, already computed in Kh
908  }
909 
910 
912  template<class T>
913  void EigenProblem_Base<T>
914  ::ComputeStiffnessMatrix(const T& a, const T& b)
915  {
916  // nothing to do, we use Kh and Mh for the matrix vector product
917  }
918 
919 
921 
925  template<class T>
926  void EigenProblem_Base<T>
927  ::ComputeAndFactorizeStiffnessMatrix(const Treal& a, const Treal& b,
928  int which_part)
929  {
930  abort();
931  }
932 
933 
935 
939  template<class T>
941  ::ComputeAndFactorizeStiffnessMatrix(const Tcplx& a, const Tcplx& b,
942  int which_part)
943  {
944  abort();
945  }
946 
947 
949  template<class T>
952  {
953  abort();
954  }
955 
956 
958  template<class T>
961  {
962  abort();
963  }
964 
965 
967  template<class T>
970  const Vector<Treal>& X, Vector<Treal>& Y)
971  {
972  abort();
973  }
974 
975 
977  template<class T>
980  const Vector<Tcplx>& X, Vector<Tcplx>& Y)
981  {
982  abort();
983  }
984 
985 
987  template<class T>
989  {
990  abort();
991  }
992 
993 
995  template<class T>
996  void EigenProblem_Base<T>
997  ::MltCholeskyMass(const SeldonTranspose& TransA, Vector<Treal>& X)
998  {
999  abort();
1000  }
1001 
1002 
1004  template<class T>
1007  {
1008  abort();
1009  }
1010 
1011 
1013  template<class T>
1016  {
1017  abort();
1018  }
1019 
1020 
1022  template<class T>
1025  {
1026  abort();
1027  }
1028 
1029 
1031  template<class T>
1033  {
1034  }
1035 
1036 
1037  /***********************
1038  * VirtualEigenProblem *
1039  ***********************/
1040 
1041 
1043  template<class T, class StiffValue, class MassValue>
1045  {
1046  Mh = NULL;
1047  Kh = NULL;
1048  }
1049 
1050 
1052 
1057  template<class T, class StiffValue, class MassValue>
1060  {
1061  Kh = &K;
1062  Mh = NULL;
1063  this->diagonal_mass = true;
1064  if ( (!K.IsSymmetric()) && (!K.IsComplex()) && (this->shift_imag != T(0)) )
1065  {
1066  // for real unsymmetric problems, if sigma is complex
1067  // we have to use mode 3 or 4 in Arpack => generalized problem
1068  this->diagonal_mass = false;
1069  }
1070 
1071  if (n == -1)
1072  this->Init(K.GetM());
1073  else
1074  this->Init(n);
1075  }
1076 
1077 
1079 
1083  template<class T, class StiffValue, class MassValue>
1086  {
1087  Kh = &K;
1088  Mh = &M;
1089  this->diagonal_mass = false;
1090 
1091  if (n == -1)
1092  this->Init(K.GetM());
1093  else
1094  this->Init(n);
1095  }
1096 
1097 
1099 
1103  template<class T, class StiffValue, class MassValue>
1106  {
1107  Kh = &K;
1108  Mh = &M;
1109  }
1110 
1111 
1113 
1117  template<class T, class StiffValue, class MassValue>
1119  ::SetTypeSpectrum(int type, const T& val, int type_sort)
1120  {
1121  EigenProblem_Base<T>::SetTypeSpectrum(type, val, type_sort);
1122  }
1123 
1124 
1126 
1130  template<class T, class StiffValue, class MassValue>
1132  ::SetTypeSpectrum(int type, const complex<T>& val, int type_sort)
1133  {
1134  EigenProblem_Base<T>::SetTypeSpectrum(type, val, type_sort);
1135 
1136  if (Kh != NULL)
1137  {
1138  if ( (!Kh->IsSymmetric())
1139  && (!Kh->IsComplex()) && (this->shift_imag != T(0)) )
1140  {
1141  // for real unsymmetric problems, if sigma is complex
1142  // we have to use mode 3 or 4 in Arpack => generalized problem
1143  this->diagonal_mass = false;
1144  }
1145  }
1146  }
1147 
1148 
1150  template<class T, class StiffValue, class MassValue>
1152  {
1153  if (Kh != NULL)
1154  {
1155  if (Kh->IsSymmetric())
1156  {
1157  if (Mh == NULL)
1158  return true;
1159  else
1160  return Mh->IsSymmetric();
1161  }
1162  }
1163  else
1164  this->PrintErrorInit();
1165 
1166  return false;
1167  }
1168 
1169 
1171  template<class T, class StiffValue, class MassValue>
1173  {
1174  if (Kh != NULL)
1175  {
1176  if (Kh->IsComplex())
1177  return false;
1178  else
1179  {
1180  if (Kh->IsSymmetric())
1181  {
1182  if (Mh == NULL)
1183  return true;
1184  else
1185  {
1186  if (Mh->IsComplex())
1187  return false;
1188 
1189  return Mh->IsSymmetric();
1190  }
1191  }
1192  }
1193  }
1194  else
1195  this->PrintErrorInit();
1196 
1197  return false;
1198  }
1199 
1200 
1202  template<class T, class StiffValue, class MassValue>
1204  {
1205  Vector<MassValue>& D = sqrt_diagonal_mass;
1206  if (Mh == NULL)
1207  {
1208  // M = identity
1209  D.Reallocate(this->n_);
1210  D.Fill(1.0);
1211  }
1212  else
1213  {
1214  cout << "not implemented for this kind of eigenproblem" << endl;
1215  abort();
1216  }
1217  }
1218 
1219 
1221  template<class T, class StiffValue, class MassValue>
1223  {
1224  Vector<MassValue>& D = sqrt_diagonal_mass;
1225  sqrt_diagonal_mass.Reallocate(D.GetM());
1226  for (int i = 0; i < D.GetM(); i++)
1227  sqrt_diagonal_mass(i) = sqrt(D(i));
1228  }
1229 
1230 
1232  template<class T, class StiffValue, class MassValue>
1234  {
1235  D.Reallocate(sqrt_diagonal_mass.GetM());
1236  for (int i = 0; i < D.GetM(); i++)
1237  D(i) = sqrt_diagonal_mass(i);
1238  }
1239 
1240 
1242  template<class T, class StiffValue, class MassValue>
1245  {
1246  for (int i = 0; i < X.GetM(); i++)
1247  X(i) /= realpart(sqrt_diagonal_mass(i));
1248  }
1249 
1250 
1252  template<class T, class StiffValue, class MassValue>
1255  {
1256  for (int i = 0; i < X.GetM(); i++)
1257  X(i) *= realpart(sqrt_diagonal_mass(i));
1258  }
1259 
1260 
1261 
1263  template<class T, class StiffValue, class MassValue>
1266  {
1267  for (int i = 0; i < X.GetM(); i++)
1268  X(i) /= sqrt_diagonal_mass(i);
1269  }
1270 
1271 
1273  template<class T, class StiffValue, class MassValue>
1276  {
1277  for (int i = 0; i < X.GetM(); i++)
1278  X(i) *= sqrt_diagonal_mass(i);
1279  }
1280 
1281 
1283  template<class T, class StiffValue, class MassValue>
1286  {
1287  if (Mh == NULL)
1288  {
1289  // default : mass matrix is identity (standard eigenvalue problem)
1290  Seldon::Copy(X, Y);
1291  }
1292  else
1293  Mh->MltVector(X, Y);
1294  }
1295 
1296 
1298  template<class T, class StiffValue, class MassValue>
1301  {
1302  if (Mh == NULL)
1303  {
1304  // default : mass matrix is identity (standard eigenvalue problem)
1305  Seldon::Copy(X, Y);
1306  }
1307  else
1308  Mh->MltVector(X, Y);
1309  }
1310 
1311 
1313  template<class T, class StiffValue, class MassValue>
1316  {
1317  if (Mh == NULL)
1318  {
1319  // default : mass matrix is identity (standard eigenvalue problem)
1320  Seldon::Copy(X, Y);
1321  }
1322  else
1323  Mh->MltVector(trans, X, Y);
1324  }
1325 
1326 
1328  template<class T, class StiffValue, class MassValue>
1331  {
1332  if (Mh == NULL)
1333  {
1334  // default : mass matrix is identity (standard eigenvalue problem)
1335  Seldon::Copy(X, Y);
1336  }
1337  else
1338  Mh->MltVector(trans, X, Y);
1339  }
1340 
1341 
1343  template<class T, class StiffValue, class MassValue>
1346  {
1347  if (Kh == NULL)
1348  this->PrintErrorInit();
1349  else
1350  Kh->MltVector(X, Y);
1351  }
1352 
1353 
1355  template<class T, class StiffValue, class MassValue>
1358  {
1359  if (Kh == NULL)
1360  this->PrintErrorInit();
1361  else
1362  Kh->MltVector(X, Y);
1363  }
1364 
1365 
1367  template<class T, class StiffValue, class MassValue>
1369  ::MltStiffness(const T& coef_massb, const T& coef_stiffb,
1370  const Vector<Treal>& X, Vector<Treal>& Y)
1371  {
1372  if (Kh == NULL)
1373  this->PrintErrorInit();
1374  else
1375  Kh->MltVector(X, Y);
1376 
1377  Treal coef_mass, coef_stiff;
1378  SetComplexReal(coef_massb, coef_mass);
1379  SetComplexReal(coef_stiffb, coef_stiff);
1380  if (coef_mass != T(0))
1381  {
1382  if (Mh == NULL)
1383  for (int i = 0; i < Y.GetM(); i++)
1384  Y(i) += coef_mass*X(i);
1385  else
1386  Mh->MltAddVector(coef_mass, X, coef_stiff, Y);
1387  }
1388  else
1389  {
1390  if (coef_stiff != T(1))
1391  Mlt(coef_stiff, Y);
1392  }
1393  }
1394 
1395 
1397  template<class T, class StiffValue, class MassValue>
1399  ::MltStiffness(const T& coef_mass, const T& coef_stiff,
1400  const Vector<Tcplx>& X, Vector<Tcplx>& Y)
1401  {
1402  if (Kh == NULL)
1403  this->PrintErrorInit();
1404  else
1405  Kh->MltVector(X, Y);
1406 
1407  if (coef_mass != T(0))
1408  {
1409  if (Mh == NULL)
1410  for (int i = 0; i < Y.GetM(); i++)
1411  Y(i) += coef_mass*X(i);
1412  else
1413  Mh->MltAddVector(coef_mass, X, coef_stiff, Y);
1414  }
1415  else
1416  {
1417  if (coef_stiff != T(1))
1418  Mlt(coef_stiff, Y);
1419  }
1420  }
1421 
1422 
1424  template<class T, class StiffValue, class MassValue>
1427  {
1428  if (Kh == NULL)
1429  this->PrintErrorInit();
1430  else
1431  Kh->MltVector(trans, X, Y);
1432  }
1433 
1434 
1436  template<class T, class StiffValue, class MassValue>
1439  {
1440  if (Kh == NULL)
1441  this->PrintErrorInit();
1442  else
1443  Kh->MltVector(trans, X, Y);
1444  }
1445 
1446 
1448  template<class T, class StiffValue, class MassValue>
1450  {
1451  sqrt_diagonal_mass.Clear();
1452  }
1453 
1454 
1455  /********************************************
1456  * Modification of eigenvalues/eigenvectors *
1457  ********************************************/
1458 
1459 
1461 
1467  template<class T0, class Prop, class Storage>
1469  Vector<T0>& eigen_values, Vector<T0>& lambda_imag,
1470  Matrix<T0, Prop, Storage>& eigen_vectors,
1471  const T0& shiftr, const T0& shifti)
1472  {
1473  if (var.DiagonalMass())
1474  {
1475  Vector<T0> sqrt_Dh;
1476  var.GetSqrtDiagonal(sqrt_Dh);
1477  // scaling to have true eigenvectors
1478  for (int i = 0; i < eigen_vectors.GetM(); i++)
1479  for (int j = 0; j < eigen_vectors.GetN(); j++)
1480  eigen_vectors(i, j) /= sqrt_Dh(i);
1481  }
1482  else if (var.UseCholeskyFactoForMass())
1483  {
1484  Vector<T0> Xcol(eigen_vectors.GetM());
1485  for (int j = 0; j < eigen_vectors.GetN(); j++)
1486  {
1487  for (int i = 0; i < eigen_vectors.GetM(); i++)
1488  Xcol(i) = eigen_vectors(i, j);
1489 
1490  var.SolveCholeskyMass(SeldonTrans, Xcol);
1491  for (int i = 0; i < eigen_vectors.GetM(); i++)
1492  eigen_vectors(i, j) = Xcol(i);
1493  }
1494  }
1495 
1496  var.DistributeEigenvectors(eigen_vectors);
1497 
1498  if (var.GetComputationalMode() != var.REGULAR_MODE)
1499  {
1500  bool use_rayleigh_coef = false;
1501  if ( (var.eigenvalue_computation_mode == var.INVERT_MODE)
1502  && (var.GetTypeSpectrum() != var.CENTERED_EIGENVALUES))
1503  {
1504  // nothing to change
1505  }
1506  else if ((var.DiagonalMass())|| (var.UseCholeskyFactoForMass())
1507  || (var.eigenvalue_computation_mode == var.INVERT_MODE))
1508  {
1509  if ( (var.GetImagShiftValue() != T0(0)) && (var.eigenvalue_computation_mode == var.INVERT_MODE))
1510  use_rayleigh_coef = true;
1511 
1512  // shift-invert mode, we have to modify eigenvalues
1513  if (!use_rayleigh_coef)
1514  for (int i = 0; i < eigen_values.GetM(); i++)
1515  {
1516  if ((eigen_values(i) == 0) && (lambda_imag(i) == 0))
1517  {
1518  eigen_values(i) = 0;
1519  lambda_imag(i) = 0;
1520  }
1521  else
1522  {
1523  complex<T0> val = 1.0/complex<T0>(eigen_values(i), lambda_imag(i))
1524  + complex<T0>(shiftr, shifti);
1525 
1526  eigen_values(i) = real(val);
1527  lambda_imag(i) = imag(val);
1528  }
1529  }
1530  }
1531  else if (var.GetImagShiftValue() != T0(0))
1532  {
1533  use_rayleigh_coef = true;
1534  }
1535 
1536  if (use_rayleigh_coef)
1537  {
1538  int n = eigen_vectors.GetM();
1539  Vector<T0> X(n), Ax(n), Mx(n), Y(n);
1540  int j = 0;
1541  Ax.Fill(T0(0));
1542  Mx.Fill(T0(0));
1543  while (j < eigen_values.GetM())
1544  {
1545  if (lambda_imag(j) == T0(0))
1546  {
1547  // real eigenvalue
1548  // lambda is retrieved by computing Rayleigh quotient
1549  for (int i = 0; i < eigen_vectors.GetM(); i++)
1550  X(i) = eigen_vectors(i,j);
1551 
1552  var.MltMass(X, Mx);
1553  var.MltStiffness(X, Ax);
1554  eigen_values(j) = DotProd(X, Ax)/DotProd(X, Mx);
1555 
1556  // next eigenvalue
1557  j++;
1558  }
1559  else
1560  {
1561  if (j == eigen_values.GetM() - 1)
1562  {
1563  eigen_values(j) = 0.0;
1564  lambda_imag(j) = 0.0;
1565 
1566  break;
1567  }
1568 
1569  // conjugate pair of eigenvalues
1570  for (int i = 0; i < eigen_vectors.GetM(); i++)
1571  {
1572  X(i) = eigen_vectors(i, j);
1573  Y(i) = eigen_vectors(i, j+1);
1574  }
1575 
1576  // complex Rayleigh quotient
1577  var.MltStiffness(X, Ax);
1578  T0 numr = DotProd(X, Ax);
1579  T0 numi = DotProd(Y, Ax);
1580 
1581  var.MltStiffness(Y, Ax);
1582  numr += DotProd(Y, Ax);
1583  numi -= DotProd(X, Ax);
1584 
1585  var.MltMass(X, Mx);
1586  T0 denr = DotProd(X, Mx);
1587  T0 deni = DotProd(Y, Mx);
1588 
1589  var.MltMass(Y, Mx);
1590  denr += DotProd(Y, Mx);
1591  deni -= DotProd(X, Mx);
1592 
1593  complex<T0> val = complex<T0>(numr, numi)/complex<T0>(denr, deni);
1594 
1595  eigen_values(j) = real(val);
1596  eigen_values(j+1) = real(val);
1597 
1598  lambda_imag(j) = -imag(val);
1599  lambda_imag(j+1) = imag(val);
1600 
1601  // next eigenvalue
1602  j += 2;
1603  }
1604  }
1605  }
1606  }
1607  }
1608 
1609 
1611 
1617  template<class T0, class Prop, class Storage>
1618  void ApplyScalingEigenvec(EigenProblem_Base<complex<T0> >& var,
1619  Vector<complex<T0> >& eigen_values,
1620  Vector<complex<T0> >& lambda_imag,
1621  Matrix<complex<T0>, Prop, Storage>& eigen_vectors,
1622  const complex<T0>& shiftr, const complex<T0>& shifti)
1623  {
1624 
1625  if (var.DiagonalMass())
1626  {
1627  Vector<complex<T0> > sqrt_Dh;
1628  var.GetSqrtDiagonal(sqrt_Dh);
1629  // scaling to have true eigenvectors
1630  for (int i = 0; i < eigen_vectors.GetM(); i++)
1631  for (int j = 0; j < eigen_vectors.GetN(); j++)
1632  eigen_vectors(i, j) /= sqrt_Dh(i);
1633  }
1634  else if (var.UseCholeskyFactoForMass())
1635  {
1636  Vector<complex<T0> > Xcol(eigen_vectors.GetM());
1637  for (int j = 0; j < eigen_vectors.GetN(); j++)
1638  {
1639  for (int i = 0; i < eigen_vectors.GetM(); i++)
1640  Xcol(i) = eigen_vectors(i, j);
1641 
1642  var.SolveCholeskyMass(SeldonTrans, Xcol);
1643  for (int i = 0; i < eigen_vectors.GetM(); i++)
1644  eigen_vectors(i, j) = Xcol(i);
1645  }
1646  }
1647 
1648  var.DistributeEigenvectors(eigen_vectors);
1649 
1650  if (var.GetComputationalMode() != var.REGULAR_MODE)
1651  {
1652  if ( (var.eigenvalue_computation_mode == var.INVERT_MODE)
1653  && (var.GetTypeSpectrum() != var.CENTERED_EIGENVALUES))
1654  {
1655  // nothing to change
1656  }
1657  else if ((var.DiagonalMass())|| (var.UseCholeskyFactoForMass())
1658  || (var.eigenvalue_computation_mode == var.INVERT_MODE))
1659  {
1660  // shift-invert mode, we have to modify eigenvalues
1661  for (int i = 0; i < eigen_values.GetM(); i++)
1662  {
1663  complex<T0> val = 1.0/eigen_values(i) + shiftr;
1664 
1665  eigen_values(i) = val;
1666  }
1667 
1668  }
1669  }
1670  }
1671 
1672 
1673  /***********************
1674  * Sorting eigenvalues *
1675  ***********************/
1676 
1677 
1679  template<class T, class Storage1, class Storage2>
1680  void SortEigenvalues(Vector<T>& lambda_r, Vector<T>& lambda_i,
1681  Matrix<T, General, Storage1>& eigen_old,
1682  Matrix<T, General, Storage2>& eigen_new,
1683  int type_spectrum, int type_sort,
1684  const T& shift_r, const T& shift_i)
1685  {
1686  int n = min(lambda_r.GetM(), long(eigen_old.GetN()));
1687 
1688  IVect permutation(n);
1689  permutation.Fill();
1690  eigen_new.Reallocate(eigen_old.GetM(), n);
1691 
1692  // creating a vector that can be sorted
1693  Vector<T> L(n); L.Fill();
1694  if (type_spectrum == EigenProblem_Base<T>::CENTERED_EIGENVALUES)
1695  {
1696  // eigenvalues closest to shift are placed at beginning
1697  switch (type_sort)
1698  {
1700  {
1701  for (int i = 0; i < n; i++)
1702  L(i) = 1.0/abs(shift_r - lambda_r(i));
1703  }
1704  break;
1706  {
1707  for (int i = 0; i < n; i++)
1708  L(i) = 1.0/abs(shift_i - lambda_i(i));
1709  }
1710  break;
1712  {
1713  for (int i = 0; i < n; i++)
1714  L(i) = 1.0/abs(complex<T>(shift_r - lambda_r(i), shift_i - lambda_i(i)));
1715  }
1716  break;
1717  }
1718  }
1719  else
1720  {
1721  // smallest eigenvalues are placed at beginning
1722  switch (type_sort)
1723  {
1725  {
1726  for (int i = 0; i < n; i++)
1727  L(i) = abs(lambda_r(i));
1728  }
1729  break;
1731  {
1732  for (int i = 0; i < n; i++)
1733  L(i) = abs(lambda_i(i));
1734  }
1735  break;
1737  {
1738  for (int i = 0; i < n; i++)
1739  L(i) = abs(complex<T>(lambda_r(i), lambda_i(i)));
1740  }
1741  break;
1742  }
1743  }
1744 
1745  // sorting L, and retrieving permutation array
1746  Sort(L, permutation);
1747 
1748  // permuting eigenvalues and eigenvectors
1749  Vector<T> oldLambda_r = lambda_r, oldLambda_i = lambda_i;
1750  for (int i = 0; i < n; i++)
1751  {
1752  lambda_r(i) = oldLambda_r(permutation(i));
1753  lambda_i(i) = oldLambda_i(permutation(i));
1754  for (int j = 0; j < eigen_old.GetM(); j++)
1755  eigen_new(j, i) = eigen_old(j, permutation(i));
1756  }
1757 
1758  }
1759 
1760 
1762  template<class T, class Storage1, class Storage2>
1763  void SortEigenvalues(Vector<complex<T> >& lambda_r, Vector<complex<T> >& lambda_i,
1764  Matrix<complex<T>, General, Storage1>& eigen_old,
1765  Matrix<complex<T>, General, Storage2>& eigen_new,
1766  int type_spectrum, int type_sort,
1767  const complex<T>& shift_r, const complex<T>& shift_i)
1768  {
1769  // complex case, ignoring lambda_i and shift_i
1770  int n = min(lambda_r.GetM(), long(eigen_old.GetN()));
1771 
1772  IVect permutation(n);
1773  permutation.Fill();
1774  eigen_new.Reallocate(eigen_old.GetM(), n);
1775 
1776  // creating a vector that can be sorted
1777  Vector<T> L(n);
1778  if (type_spectrum == EigenProblem_Base<T>::CENTERED_EIGENVALUES)
1779  {
1780  // eigenvalues closest to shift are placed at beginning
1781  switch (type_sort)
1782  {
1784  {
1785  for (int i = 0; i < n; i++)
1786  L(i) = 1.0/abs(real(shift_r - lambda_r(i)));
1787  }
1788  break;
1790  {
1791  for (int i = 0; i < n; i++)
1792  L(i) = 1.0/abs(imag(shift_r - lambda_r(i)));
1793  }
1794  break;
1796  {
1797  for (int i = 0; i < n; i++)
1798  L(i) = 1.0/abs(shift_r - lambda_r(i));
1799  }
1800  break;
1801  }
1802  }
1803  else
1804  {
1805  // smallest eigenvalues are placed at beginning
1806  switch (type_sort)
1807  {
1809  {
1810  for (int i = 0; i < n; i++)
1811  L(i) = abs(real(lambda_r(i)));
1812  }
1813  break;
1815  {
1816  for (int i = 0; i < n; i++)
1817  L(i) = abs(imag(lambda_r(i)));
1818  }
1819  break;
1821  {
1822  for (int i = 0; i < n; i++)
1823  L(i) = abs(lambda_r(i));
1824  }
1825  break;
1826  }
1827  }
1828 
1829  // sorting L, and retrieving permutation array
1830  Sort(L, permutation);
1831 
1832  // permuting eigenvalues and eigenvectors
1833  Vector<complex<T> > oldLambda_r = lambda_r, oldLambda_i = lambda_i;
1834  for (int i = 0; i < n; i++)
1835  {
1836  lambda_r(i) = oldLambda_r(permutation(i));
1837  lambda_i(i) = oldLambda_i(permutation(i));
1838  for (int j = 0; j < eigen_old.GetM(); j++)
1839  eigen_new(j, i) = eigen_old(j, permutation(i));
1840  }
1841 
1842  }
1843 
1844 
1845  /*********************
1846  * DenseEigenProblem *
1847  *********************/
1848 
1849 
1851  template<class T, class Tstiff, class Prop, class Storage,
1852  class Tmass, class PropM, class StorageM>
1853  DenseEigenProblem<T, Tstiff, Prop, Storage, Tmass, PropM, StorageM>::
1854  DenseEigenProblem() : VirtualEigenProblem<T, Tstiff, Tmass>()
1855  {
1856  Mh = NULL;
1857  Kh = NULL;
1858  }
1859 
1860 
1862  template<class T, class Tstiff, class Prop, class Storage,
1863  class Tmass, class PropM, class StorageM>
1864  void DenseEigenProblem<T, Tstiff, Prop, Storage, Tmass, PropM, StorageM>
1866  {
1868  Kh = &K;
1869  Mh = NULL;
1870  }
1871 
1872 
1874  template<class T, class Tstiff, class Prop, class Storage,
1875  class Tmass, class PropM, class StorageM>
1879  {
1881  Kh = &K;
1882  Mh = &M;
1883  }
1884 
1885 
1887  template<class T, class Tstiff, class Prop, class Storage,
1888  class Tmass, class PropM, class StorageM>
1891  {
1892  Vector<Tmass>& D = this->sqrt_diagonal_mass;
1893  if (Mh == NULL)
1894  {
1895  // M = identity
1896  D.Reallocate(this->n_);
1897  D.Fill(1.0);
1898  }
1899  else
1900  {
1901  D.Reallocate(this->n_);
1902  for (int i = 0; i < this->n_; i++)
1903  D(i) = (*Mh)(i, i);
1904  }
1905  }
1906 
1907 
1909  template<class T, class Tstiff, class Prop, class Storage,
1910  class Tmass, class PropM, class StorageM>
1913  {
1914  if (Mh == NULL)
1915  {
1916  mat_chol.Reallocate(this->n_, this->n_);
1917  mat_chol.SetIdentity();
1918  }
1919  else
1920  {
1921  mat_chol = *(Mh);
1922  GetCholesky(mat_chol);
1923  Xchol_real.Reallocate(mat_chol.GetM());
1924  Xchol_imag.Reallocate(mat_chol.GetM());
1925  }
1926  }
1927 
1928 
1930  template<class T, class Tstiff, class Prop, class Storage,
1931  class Tmass, class PropM, class StorageM>
1932  void DenseEigenProblem<T, Tstiff, Prop, Storage, Tmass, PropM, StorageM>::
1933  MltCholeskyMass(const SeldonTranspose& transA, Vector<Treal>& X)
1934  {
1935  MltCholesky(transA, mat_chol, X);
1936  }
1937 
1938 
1940  template<class T, class Tstiff, class Prop, class Storage,
1941  class Tmass, class PropM, class StorageM>
1944  {
1945  for (int i = 0; i < X.GetM(); i++)
1946  {
1947  Xchol_real(i) = real(X(i));
1948  Xchol_imag(i) = imag(X(i));
1949  }
1950 
1951  MltCholesky(transA, mat_chol, Xchol_real);
1952  MltCholesky(transA, mat_chol, Xchol_imag);
1953 
1954  for (int i = 0; i < X.GetM(); i++)
1955  X(i) = complex<Treal>(Xchol_real(i), Xchol_imag(i));
1956  }
1957 
1958 
1960  template<class T, class Tstiff, class Prop, class Storage,
1961  class Tmass, class PropM, class StorageM>
1964  {
1965  SolveCholesky(transA, mat_chol, X);
1966  }
1967 
1968 
1970  template<class T, class Tstiff, class Prop, class Storage,
1971  class Tmass, class PropM, class StorageM>
1974  {
1975  for (int i = 0; i < X.GetM(); i++)
1976  {
1977  Xchol_real(i) = real(X(i));
1978  Xchol_imag(i) = imag(X(i));
1979  }
1980 
1981  SolveCholesky(transA, mat_chol, Xchol_real);
1982  SolveCholesky(transA, mat_chol, Xchol_imag);
1983 
1984  for (int i = 0; i < X.GetM(); i++)
1985  X(i) = complex<Treal>(Xchol_real(i), Xchol_imag(i));
1986  }
1987 
1988 
1990  template<class T, class Tstiff, class Prop, class Storage,
1991  class Tmass, class PropM, class StorageM>
1994  {
1995  if (Mh == NULL)
1996  {
1997  // default : mass matrix is identity (standard eigenvalue problem)
1998  Seldon::Copy(X, Y);
1999  }
2000  else
2001  Mlt(*Mh, X, Y);
2002  }
2003 
2004 
2006  template<class T, class Tstiff, class Prop, class Storage,
2007  class Tmass, class PropM, class StorageM>
2010  {
2011  if (Mh == NULL)
2012  {
2013  // default : mass matrix is identity (standard eigenvalue problem)
2014  Seldon::Copy(X, Y);
2015  }
2016  else
2017  Mlt(*Mh, X, Y);
2018  }
2019 
2020 
2022  template<class T, class Tstiff, class Prop, class Storage,
2023  class Tmass, class PropM, class StorageM>
2026  {
2027  if (Mh == NULL)
2028  {
2029  // default : mass matrix is identity (standard eigenvalue problem)
2030  Seldon::Copy(X, Y);
2031  }
2032  else
2033  Mlt(trans, *Mh, X, Y);
2034  }
2035 
2036 
2038  template<class T, class Tstiff, class Prop, class Storage,
2039  class Tmass, class PropM, class StorageM>
2042  {
2043  if (Mh == NULL)
2044  {
2045  // default : mass matrix is identity (standard eigenvalue problem)
2046  Seldon::Copy(X, Y);
2047  }
2048  else
2049  Mlt(trans, *Mh, X, Y);
2050  }
2051 
2052 
2054  template<class T, class Tstiff, class Prop, class Storage,
2055  class Tmass, class PropM, class StorageM>
2058  {
2059  if (Kh == NULL)
2060  this->PrintErrorInit();
2061  else
2062  Mlt(*Kh, X, Y);
2063  }
2064 
2065 
2067  template<class T, class Tstiff, class Prop, class Storage,
2068  class Tmass, class PropM, class StorageM>
2071  {
2072  if (Kh == NULL)
2073  this->PrintErrorInit();
2074  else
2075  Mlt(*Kh, X, Y);
2076  }
2077 
2078 
2080  template<class T, class Tstiff, class Prop, class Storage,
2081  class Tmass, class PropM, class StorageM>
2083  ::MltStiffness(const T& coef_massb, const T& coef_stiffb,
2084  const Vector<Treal>& X, Vector<Treal>& Y)
2085  {
2086  if (Kh == NULL)
2087  this->PrintErrorInit();
2088  else
2089  Mlt(*Kh, X, Y);
2090 
2091  Treal coef_mass, coef_stiff;
2092  SetComplexReal(coef_massb, coef_mass);
2093  SetComplexReal(coef_stiffb, coef_stiff);
2094  if (coef_mass != T(0))
2095  {
2096  if (Mh == NULL)
2097  for (int i = 0; i < Y.GetM(); i++)
2098  Y(i) += coef_mass*X(i);
2099  else
2100  MltAdd(coef_mass, *Mh, X, coef_stiff, Y);
2101  }
2102  else
2103  {
2104  if (coef_stiff != T(1))
2105  Mlt(coef_stiff, Y);
2106  }
2107  }
2108 
2109 
2111  template<class T, class Tstiff, class Prop, class Storage,
2112  class Tmass, class PropM, class StorageM>
2114  ::MltStiffness(const T& coef_mass, const T& coef_stiff,
2115  const Vector<Tcplx>& X, Vector<Tcplx>& Y)
2116  {
2117  if (Kh == NULL)
2118  this->PrintErrorInit();
2119  else
2120  Mlt(*Kh, X, Y);
2121 
2122  if (coef_mass != T(0))
2123  {
2124  if (Mh == NULL)
2125  for (int i = 0; i < Y.GetM(); i++)
2126  Y(i) += coef_mass*X(i);
2127  else
2128  MltAdd(coef_mass, *Mh, X, coef_stiff, Y);
2129  }
2130  else
2131  {
2132  if (coef_stiff != T(1))
2133  Mlt(coef_stiff, Y);
2134  }
2135  }
2136 
2137 
2139  template<class T, class Tstiff, class Prop, class Storage,
2140  class Tmass, class PropM, class StorageM>
2143  {
2144  if (Kh == NULL)
2145  this->PrintErrorInit();
2146  else
2147  Mlt(SeldonTrans, *Kh, X, Y);
2148  }
2149 
2150 
2152  template<class T, class Tstiff, class Prop, class Storage,
2153  class Tmass, class PropM, class StorageM>
2156  {
2157  if (Kh == NULL)
2158  this->PrintErrorInit();
2159  else
2160  Mlt(SeldonTrans, *Kh, X, Y);
2161  }
2162 
2163 
2165  template<class T, class Tstiff, class Prop, class Storage,
2166  class Tmass, class PropM, class StorageM>
2168  ::ComputeAndFactorizeStiffnessMatrix(const Treal& a, const Treal& b,
2169  int which_part)
2170  {
2171  ComputeAndFactoRealMatrix(T(0), a, b, which_part);
2172  }
2173 
2174 
2176  template<class T, class Tstiff, class Prop, class Storage,
2177  class Tmass, class PropM, class StorageM>
2179  ::ComputeAndFactoRealMatrix(const Tcplx&, const Treal& a, const Treal& b, int which)
2180  {
2181  cout << "Provide coefficients a and b of the same type as T" << endl;
2182  abort();
2183  }
2184 
2185 
2187  template<class T, class Tstiff, class Prop, class Storage,
2188  class Tmass, class PropM, class StorageM>
2190  ::ComputeAndFactoRealMatrix(const Treal&, const Treal& a,
2191  const Treal& b, int which_part)
2192  {
2193  this->selected_part = which_part;
2194  if (Kh == NULL)
2195  this->PrintErrorInit();
2196 
2197  this->complex_system = false;
2198  // computation of mat_lu = a M + b K
2199  Copy(*Kh, mat_lu_real);
2200  Mlt(b, mat_lu_real);
2201  if (Mh == NULL)
2202  {
2203  for (int i = 0; i < this->n_; i++)
2204  mat_lu_real(i, i) += a;
2205  }
2206  else
2207  Add(a, *Mh, mat_lu_real);
2208 
2209  // factorisation
2210  GetLU(mat_lu_real, pivot);
2211  }
2212 
2213 
2215  template<class T, class Tstiff, class Prop, class Storage,
2216  class Tmass, class PropM, class StorageM>
2218  ComputeAndFactorizeStiffnessMatrix(const Tcplx& a, const Tcplx& b,
2219  int which_part)
2220  {
2221  this->selected_part = which_part;
2222  if (Kh == NULL)
2223  this->PrintErrorInit();
2224 
2225  this->complex_system = true;
2226  // inverse of (a M + b K), then we take real_part or imaginary part
2227  Matrix<Tcplx, Prop, Storage> InvMat(this->n_, this->n_);
2228  for (int i = 0; i < this->n_; i++)
2229  for (int j = 0; j < this->n_; j++)
2230  InvMat(i, j) = (*Kh)(i, j);
2231 
2232  Mlt(b, InvMat);
2233  if (Mh == NULL)
2234  {
2235  for (int i = 0; i < this->n_; i++)
2236  InvMat(i, i) += a;
2237  }
2238  else
2239  {
2240  for (int i = 0; i < this->n_; i++)
2241  for (int j = 0; j < this->n_; j++)
2242  InvMat(i, j) += a * (*this->Mh)(i, j);
2243  }
2244 
2245  if (which_part == EigenProblem_Base<T>::COMPLEX_PART)
2246  {
2247  mat_lu_cplx = InvMat;
2248  InvMat.Clear();
2249  GetLU(mat_lu_cplx, pivot);
2250  }
2251  else
2252  {
2253  // inverse
2254  GetInverse(InvMat);
2255 
2256  // then extracting real or imaginary part
2257  mat_lu_real.Reallocate(this->n_, this->n_);
2258  if (which_part == EigenProblem_Base<T>::REAL_PART)
2259  {
2260  for (int i = 0; i < this->n_; i++)
2261  for (int j = 0; j < this->n_; j++)
2262  mat_lu_real(i, j) = real(InvMat(i, j));
2263  }
2264  else
2265  {
2266  for (int i = 0; i < this->n_; i++)
2267  for (int j = 0; j < this->n_; j++)
2268  mat_lu_real(i, j) = imag(InvMat(i, j));
2269  }
2270  }
2271  }
2272 
2273 
2275  template<class T, class Tstiff, class Prop, class Storage,
2276  class Tmass, class PropM, class StorageM>
2279  {
2280  if (this->complex_system)
2281  {
2282  if (this->selected_part == EigenProblem_Base<T>::COMPLEX_PART)
2283  {
2284  cout << "The result can not be a real vector" << endl;
2285  abort();
2286  }
2287 
2288  Mlt(mat_lu_real, X, Y);
2289  }
2290  else
2291  {
2292  Copy(X, Y);
2293  SolveLU(mat_lu_real, pivot, Y);
2294  }
2295  }
2296 
2297 
2299  template<class T, class Tstiff, class Prop, class Storage,
2300  class Tmass, class PropM, class StorageM>
2303  {
2304  if (this->complex_system)
2305  {
2306  if (this->selected_part == EigenProblem_Base<T>::COMPLEX_PART)
2307  {
2308  Copy(X, Y);
2309  SolveLU(mat_lu_cplx, pivot, Y);
2310  }
2311  else
2312  Mlt(mat_lu_real, X, Y);
2313  }
2314  else
2315  {
2316  Copy(X, Y);
2317  SolveLU(mat_lu_real, pivot, Y);
2318  }
2319  }
2320 
2321 
2323  template<class T, class Tstiff, class Prop, class Storage,
2324  class Tmass, class PropM, class StorageM>
2327  const Vector<Treal>& X, Vector<Treal>& Y)
2328  {
2329  if (this->complex_system)
2330  {
2331  if (this->selected_part == EigenProblem_Base<T>::COMPLEX_PART)
2332  {
2333  cout << "The result can not be a real vector" << endl;
2334  abort();
2335  }
2336 
2337  Mlt(transA, mat_lu_real, X, Y);
2338  }
2339  else
2340  {
2341  Copy(X, Y);
2342  SolveLU(transA, mat_lu_real, pivot, Y);
2343  }
2344  }
2345 
2346 
2348  template<class T, class Tstiff, class Prop, class Storage,
2349  class Tmass, class PropM, class StorageM>
2352  const Vector<Tcplx>& X, Vector<Tcplx>& Y)
2353  {
2354  if (this->complex_system)
2355  {
2356  if (this->selected_part == EigenProblem_Base<T>::COMPLEX_PART)
2357  {
2358  Copy(X, Y);
2359  SolveLU(transA, mat_lu_cplx, pivot, Y);
2360  }
2361  else
2362  Mlt(transA, mat_lu_real, X, Y);
2363  }
2364  else
2365  {
2366  Copy(X, Y);
2367  SolveLU(transA, mat_lu_real, pivot, Y);
2368  }
2369  }
2370 
2371 
2373  template<class T, class Tstiff, class Prop, class Storage,
2374  class Tmass, class PropM, class StorageM>
2376  Clear()
2377  {
2379 
2380  mat_lu_real.Clear();
2381  mat_lu_cplx.Clear();
2382  mat_chol.Clear();
2383  }
2384 
2385 
2386  /**********************
2387  * SparseEigenProblem *
2388  **********************/
2389 
2390 
2392  template<class T, class MatStiff, class MatMass>
2393  SparseEigenProblem<T, MatStiff, MatMass>::
2394  SparseEigenProblem()
2395  : VirtualEigenProblem<T, typename MatStiff::entry_type,
2396  typename MatMass::entry_type>()
2397  {
2398  mat_lu_real.RefineSolution();
2399  mat_lu_cplx.RefineSolution();
2400  Mh = NULL;
2401  Kh = NULL;
2402  ProcSharingRows = NULL;
2403  SharingRowNumbers = NULL;
2404  nodl_scalar_ = nb_unknowns_scal_ = 0;
2405  nloc = 0;
2406  }
2407 
2408 
2410  template<class T, class MatStiff, class MatMass>
2412  {
2413  chol_facto_mass_matrix.SelectDirectSolver(type);
2414  }
2415 
2416 
2417  template<class T, class MatStiff, class MatMass>
2418  int SparseEigenProblem<T, MatStiff, MatMass>::RetrieveLocalNumbers(MatStiff& K)
2419  {
2420  nloc = K.GetM();
2421 
2422 #ifdef SELDON_WITH_MPI
2423  try
2424  {
2425  DistributedMatrix_Base<typename MatStiff::entry_type>& A
2426  = dynamic_cast<DistributedMatrix_Base<typename MatStiff::entry_type>& >(K);
2427 
2428  MPI_Comm comm = A.GetCommunicator();
2429  this->SetCommunicator(comm);
2430  int nb_proc;
2431  MPI_Comm_size(comm, &nb_proc);
2432 
2433  // only one processor => sequential case
2434  if (nb_proc <= 1)
2435  return -1;
2436 
2437  // parallel case
2438  int m = A.GetLocalM();
2439  const IVect& OverlapRow = A.GetOverlapRowNumber();
2440  int noverlap = OverlapRow.GetM();
2441  int n = m - noverlap;
2442  local_col_numbers.Reallocate(n);
2443  Vector<bool> OverlappedRow(m); OverlappedRow.Fill(false);
2444  for (int i = 0; i < noverlap; i++)
2445  OverlappedRow(OverlapRow(i)) = true;
2446 
2447  int ncol = 0;
2448  for (int i = 0; i < m; i++)
2449  if (!OverlappedRow(i))
2450  local_col_numbers(ncol++) = i;
2451 
2452  ProcSharingRows = &A.GetProcessorSharingRows();
2453  SharingRowNumbers = &A.GetSharingRowNumbers();
2454  nodl_scalar_ = A.GetNodlScalar();
2455  nb_unknowns_scal_ = A.GetNbScalarUnknowns();
2456 
2457  return n;
2458  }
2459  catch (const std::bad_cast&)
2460  {
2461  // a sequential matrix has been provided
2462  this->SetCommunicator(MPI_COMM_SELF);
2463 
2464  local_col_numbers.Clear();
2465  }
2466 #endif
2467 
2468  return -1;
2469  }
2470 
2471 
2472  template<class T, class MatStiff, class MatMass>
2473  void SparseEigenProblem<T, MatStiff, MatMass>::InitMatrix(MatStiff& K)
2474  {
2475  int n = RetrieveLocalNumbers(K);
2476  distributed = false;
2477  if (n >= 0)
2478  distributed = true;
2479 
2480  VirtualEigenProblem<T, typename MatStiff::entry_type,
2481  typename MatMass::entry_type>::InitMatrix(K, n);
2482  Kh = &K;
2483  Mh = NULL;
2484  }
2485 
2486 
2487  template<class T, class MatStiff, class MatMass>
2488  void SparseEigenProblem<T, MatStiff, MatMass>
2489  ::InitMatrix(MatStiff& K, MatMass& M)
2490  {
2491  int n = RetrieveLocalNumbers(K);
2492  distributed = false;
2493  if (n >= 0)
2494  distributed = true;
2495 
2496  VirtualEigenProblem<T, typename MatStiff::entry_type,
2497  typename MatMass::entry_type>::InitMatrix(K, M, n);
2498 
2499  Kh = &K;
2500  Mh = &M;
2501  }
2502 
2503 
2505  template<class T, class MatStiff, class MatMass>
2507  {
2508  Vector<typename MatMass::entry_type>& D = this->sqrt_diagonal_mass;
2509  if (Mh == NULL)
2510  {
2511  // M = identity
2512  D.Reallocate(this->n_);
2513  D.Fill(1.0);
2514  }
2515  else
2516  {
2517  D.Reallocate(nloc);
2518  for (int i = 0; i < nloc; i++)
2519  D(i) = (*Mh)(i, i);
2520 
2521 #ifdef SELDON_WITH_MPI
2522  // D is assembled for distributed matrices
2523  if (distributed)
2524  {
2526  AssembleVector(M, MPI_SUM, *ProcSharingRows, *SharingRowNumbers,
2527  this->comm, nodl_scalar_, nb_unknowns_scal_, 15);
2528 
2529  D.Reallocate(local_col_numbers.GetM());
2530  for (int i = 0; i < local_col_numbers.GetM(); i++)
2531  D(i) = M(local_col_numbers(i));
2532  }
2533 #endif
2534  }
2535  }
2536 
2537 
2539  template<class T, class MatStiff, class MatMass>
2541  {
2542  if (Mh == NULL)
2543  this->PrintErrorInit();
2544 
2545  int rank_rci = 0;
2546 #ifdef SELDON_WITH_MPI
2547  MPI_Comm_rank(this->rci_comm, &rank_rci);
2548 #endif
2549 
2550  if ((this->print_level > 2) && (rank_rci == 0))
2551  chol_facto_mass_matrix.ShowMessages();
2552 
2553  FactorizeCholeskyMass(*Mh);
2554 
2555  chol_facto_mass_matrix.HideMessages();
2556 
2557  Xchol_real.Reallocate(nloc);
2558  Xchol_imag.Reallocate(nloc);
2559  }
2560 
2561 
2563  template<class T, class MatStiff, class MatMass>
2564  template<class Storage>
2567  {
2568  chol_facto_mass_matrix.Factorize(M, true);
2569  }
2570 
2571 
2573  template<class T, class MatStiff, class MatMass>
2574  template<class T0, class Prop, class Storage>
2577  {
2578  cout << "Cholesky factorisation has not been implemented "
2579  << "for complex matrices" << endl;
2580  abort();
2581  }
2582 
2583 
2584 #ifdef SELDON_WITH_MPI
2585  template<class T, class MatStiff, class MatMass>
2587  template<class Storage>
2590  {
2591  chol_facto_mass_matrix.Factorize(M, true);
2592  }
2593 
2594 
2596  template<class T, class MatStiff, class MatMass>
2597  template<class T0, class Prop, class Storage>
2599  FactorizeCholeskyMass(DistributedMatrix<T0, Prop, Storage>& M)
2600  {
2601  cout << "Cholesky factorisation has not been implemented "
2602  << "for complex matrices" << endl;
2603  abort();
2604  }
2605 #endif
2606 
2607 
2609  template<class T, class MatStiff, class MatMass>
2612  {
2613  if (distributed)
2614  {
2615 #ifdef SELDON_WITH_MPI
2616  Xchol_real.Reallocate(nloc);
2617  Xchol_real.Zero();
2618  for (int i = 0; i < this->n_; i++)
2619  Xchol_real(local_col_numbers(i)) = X(i);
2620 
2621  // actually assemble is not needed since the direct solver
2622  // should extract only local values
2623  //AssembleVector(Xchol_real, MPI_SUM, *ProcSharingRows, *SharingRowNumbers,
2624  // this->comm, nodl_scalar_, nb_unknowns_scal_, 16);
2625 #endif
2626  }
2627  else
2628  Xchol_real = X;
2629 
2630  chol_facto_mass_matrix.Mlt(TransA, Xchol_real, false);
2631 
2632  if (distributed)
2633  {
2634 #ifdef SELDON_WITH_MPI
2635  for (int i = 0; i < this->n_; i++)
2636  X(i) = Xchol_real(local_col_numbers(i));
2637 #endif
2638  }
2639  else
2640  Copy(Xchol_real, X);
2641  }
2642 
2643 
2645  template<class T, class MatStiff, class MatMass>
2648  {
2649  if (distributed)
2650  {
2651 #ifdef SELDON_WITH_MPI
2652  Xchol_real.Reallocate(nloc);
2653  Xchol_real.Zero();
2654  for (int i = 0; i < this->n_; i++)
2655  Xchol_real(local_col_numbers(i)) = X(i);
2656 
2657  // actually assemble is not needed since the direct solver
2658  // should extract only local values
2659  //AssembleVector(Xchol_real, MPI_SUM, *ProcSharingRows, *SharingRowNumbers,
2660  // this->comm, nodl_scalar_, nb_unknowns_scal_, 16);
2661 #endif
2662  }
2663  else
2664  Xchol_real = X;
2665 
2666  chol_facto_mass_matrix.Solve(TransA, Xchol_real, false);
2667 
2668  if (distributed)
2669  {
2670 #ifdef SELDON_WITH_MPI
2671  for (int i = 0; i < this->n_; i++)
2672  X(i) = Xchol_real(local_col_numbers(i));
2673 #endif
2674  }
2675  else
2676  Copy(Xchol_real, X);
2677  }
2678 
2679 
2681  template<class T, class MatStiff, class MatMass>
2684  {
2685  if (distributed)
2686  {
2687 #ifdef SELDON_WITH_MPI
2688  Xchol_real.Reallocate(nloc);
2689  Xchol_imag.Reallocate(nloc);
2690  for (int i = 0; i < this->n_; i++)
2691  {
2692  Xchol_real(local_col_numbers(i)) = real(X(i));
2693  Xchol_imag(local_col_numbers(i)) = imag(X(i));
2694  }
2695 
2696  // actually assemble is not needed since the direct solver
2697  // should extract only local values
2698  //AssembleVector(Xcplx, MPI_SUM, *ProcSharingRows, *SharingRowNumbers,
2699  // this->comm, nodl_scalar_, nb_unknowns_scal_, 16);
2700 #endif
2701  }
2702  else
2703  for (int i = 0; i < X.GetM(); i++)
2704  {
2705  Xchol_real(i) = real(X(i));
2706  Xchol_imag(i) = imag(X(i));
2707  }
2708 
2709  chol_facto_mass_matrix.Mlt(TransA, Xchol_real, false);
2710  chol_facto_mass_matrix.Mlt(TransA, Xchol_imag, false);
2711 
2712  if (distributed)
2713  {
2714 #ifdef SELDON_WITH_MPI
2715  for (int i = 0; i < this->n_; i++)
2716  X(i) = complex<Treal>(Xchol_real(local_col_numbers(i)), Xchol_imag(local_col_numbers(i)));
2717 #endif
2718  }
2719  else
2720  for (int i = 0; i < X.GetM(); i++)
2721  X(i) = complex<Treal>(Xchol_real(i), Xchol_imag(i));
2722  }
2723 
2724 
2726  template<class T, class MatStiff, class MatMass>
2729  {
2730  if (distributed)
2731  {
2732 #ifdef SELDON_WITH_MPI
2733  Xchol_real.Reallocate(nloc);
2734  Xchol_imag.Reallocate(nloc);
2735  for (int i = 0; i < this->n_; i++)
2736  {
2737  Xchol_real(local_col_numbers(i)) = real(X(i));
2738  Xchol_imag(local_col_numbers(i)) = imag(X(i));
2739  }
2740 
2741  // actually assemble is not needed since the direct solver
2742  // should extract only local values
2743  //AssembleVector(Xcplx, MPI_SUM, *ProcSharingRows, *SharingRowNumbers,
2744  // this->comm, nodl_scalar_, nb_unknowns_scal_, 16);
2745 #endif
2746  }
2747  else
2748  for (int i = 0; i < X.GetM(); i++)
2749  {
2750  Xchol_real(i) = real(X(i));
2751  Xchol_imag(i) = imag(X(i));
2752  }
2753 
2754  chol_facto_mass_matrix.Solve(TransA, Xchol_real, false);
2755  chol_facto_mass_matrix.Solve(TransA, Xchol_imag, false);
2756 
2757  if (distributed)
2758  {
2759 #ifdef SELDON_WITH_MPI
2760  for (int i = 0; i < this->n_; i++)
2761  X(i) = complex<Treal>(Xchol_real(local_col_numbers(i)), Xchol_imag(local_col_numbers(i)));
2762 #endif
2763  }
2764  else
2765  for (int i = 0; i < X.GetM(); i++)
2766  X(i) = complex<Treal>(Xchol_real(i), Xchol_imag(i));
2767  }
2768 
2769 
2771  template<class T, class MatStiff, class MatMass>
2773  {
2774  if (Mh == NULL)
2775  Seldon::Copy(X, Y);
2776  else
2777  {
2778  if (distributed)
2779  {
2780 #ifdef SELDON_WITH_MPI
2781  Vector<Treal> Xcplx(nloc), Ycplx(nloc);
2782  Xcplx.Zero();
2783  for (int i = 0; i < this->n_; i++)
2784  Xcplx(local_col_numbers(i)) = X(i);
2785 
2786  AssembleVector(Xcplx, MPI_SUM, *ProcSharingRows, *SharingRowNumbers,
2787  this->comm, nodl_scalar_, nb_unknowns_scal_, 17);
2788 
2789  Mh->MltVector(Xcplx, Ycplx);
2790 
2791  for (int i = 0; i < this->n_; i++)
2792  Y(i) = Ycplx(local_col_numbers(i));
2793 #endif
2794  }
2795  else
2796  Mh->MltVector(X, Y);
2797  }
2798  }
2799 
2800 
2802  template<class T, class MatStiff, class MatMass>
2804  {
2805  if (Mh == NULL)
2806  Seldon::Copy(X, Y);
2807  else
2808  {
2809  if (distributed)
2810  {
2811 #ifdef SELDON_WITH_MPI
2812  Vector<Tcplx> Xcplx(nloc), Ycplx(nloc);
2813  Xcplx.Zero();
2814  for (int i = 0; i < this->n_; i++)
2815  Xcplx(local_col_numbers(i)) = X(i);
2816 
2817  AssembleVector(Xcplx, MPI_SUM, *ProcSharingRows, *SharingRowNumbers,
2818  this->comm, nodl_scalar_, nb_unknowns_scal_, 17);
2819 
2820  Mh->MltVector(Xcplx, Ycplx);
2821 
2822  for (int i = 0; i < this->n_; i++)
2823  Y(i) = Ycplx(local_col_numbers(i));
2824 #endif
2825  }
2826  else
2827  Mh->MltVector(X, Y);
2828  }
2829  }
2830 
2831 
2833  template<class T, class MatStiff, class MatMass>
2836  {
2837  if (Mh == NULL)
2838  Seldon::Copy(X, Y);
2839  else
2840  {
2841  if (distributed)
2842  {
2843 #ifdef SELDON_WITH_MPI
2844  Vector<Treal> Xcplx(nloc), Ycplx(nloc);
2845  Xcplx.Zero();
2846  for (int i = 0; i < this->n_; i++)
2847  Xcplx(local_col_numbers(i)) = X(i);
2848 
2849  AssembleVector(Xcplx, MPI_SUM, *ProcSharingRows, *SharingRowNumbers,
2850  this->comm, nodl_scalar_, nb_unknowns_scal_, 17);
2851 
2852  Mh->MltVector(trans, Xcplx, Ycplx);
2853 
2854  for (int i = 0; i < this->n_; i++)
2855  Y(i) = Ycplx(local_col_numbers(i));
2856 #endif
2857  }
2858  else
2859  Mh->MltVector(trans, X, Y);
2860  }
2861  }
2862 
2863 
2865  template<class T, class MatStiff, class MatMass>
2868  {
2869  if (Mh == NULL)
2870  Seldon::Copy(X, Y);
2871  else
2872  {
2873  if (distributed)
2874  {
2875 #ifdef SELDON_WITH_MPI
2876  Vector<Tcplx> Xcplx(nloc), Ycplx(nloc);
2877  Xcplx.Zero();
2878  for (int i = 0; i < this->n_; i++)
2879  Xcplx(local_col_numbers(i)) = X(i);
2880 
2881  AssembleVector(Xcplx, MPI_SUM, *ProcSharingRows, *SharingRowNumbers,
2882  this->comm, nodl_scalar_, nb_unknowns_scal_, 17);
2883 
2884  Mh->MltVector(trans, Xcplx, Ycplx);
2885 
2886  for (int i = 0; i < this->n_; i++)
2887  Y(i) = Ycplx(local_col_numbers(i));
2888 #endif
2889  }
2890  else
2891  Mh->MltVector(trans, X, Y);
2892  }
2893  }
2894 
2895 
2897  template<class T, class MatStiff, class MatMass>
2900  {
2901  if (Kh == NULL)
2902  this->PrintErrorInit();
2903  else
2904  {
2905  if (distributed)
2906  {
2907 #ifdef SELDON_WITH_MPI
2908  Vector<Treal> Xcplx(nloc), Ycplx(nloc);
2909  Xcplx.Zero();
2910  for (int i = 0; i < this->n_; i++)
2911  Xcplx(local_col_numbers(i)) = X(i);
2912 
2913  AssembleVector(Xcplx, MPI_SUM, *ProcSharingRows, *SharingRowNumbers,
2914  this->comm, nodl_scalar_, nb_unknowns_scal_, 17);
2915 
2916  Kh->MltVector(Xcplx, Ycplx);
2917 
2918  for (int i = 0; i < this->n_; i++)
2919  Y(i) = Ycplx(local_col_numbers(i));
2920 #endif
2921  }
2922  else
2923  Kh->MltVector(X, Y);
2924  }
2925  }
2926 
2927 
2929  template<class T, class MatStiff, class MatMass>
2932  {
2933  if (Kh == NULL)
2934  this->PrintErrorInit();
2935  else
2936  {
2937  if (distributed)
2938  {
2939 #ifdef SELDON_WITH_MPI
2940  Vector<Tcplx> Xcplx(nloc), Ycplx(nloc);
2941  Xcplx.Zero();
2942  for (int i = 0; i < this->n_; i++)
2943  Xcplx(local_col_numbers(i)) = X(i);
2944 
2945  AssembleVector(Xcplx, MPI_SUM, *ProcSharingRows, *SharingRowNumbers,
2946  this->comm, nodl_scalar_, nb_unknowns_scal_, 17);
2947 
2948  Kh->MltVector(Xcplx, Ycplx);
2949 
2950  for (int i = 0; i < this->n_; i++)
2951  Y(i) = Ycplx(local_col_numbers(i));
2952 #endif
2953  }
2954  else
2955  Kh->MltVector(X, Y);
2956  }
2957  }
2958 
2959 
2961  template<class T, class MatStiff, class MatMass>
2963  ::MltStiffness(const T& coef_massb, const T& coef_stiffb,
2964  const Vector<Treal>& X, Vector<Treal>& Y)
2965  {
2966  if (Kh == NULL)
2967  this->PrintErrorInit();
2968  else
2969  {
2970  if (distributed)
2971  {
2972 
2973 #ifdef SELDON_WITH_MPI
2974  Treal coef_mass, coef_stiff;
2975  SetComplexReal(coef_massb, coef_mass);
2976  SetComplexReal(coef_stiffb, coef_stiff);
2977 
2978  Vector<Treal> Xcplx(nloc), Ycplx(nloc);
2979  Xcplx.Zero();
2980  for (int i = 0; i < this->n_; i++)
2981  Xcplx(local_col_numbers(i)) = X(i);
2982 
2983  AssembleVector(Xcplx, MPI_SUM, *ProcSharingRows, *SharingRowNumbers,
2984  this->comm, nodl_scalar_, nb_unknowns_scal_, 17);
2985 
2986  Kh->MltVector(Xcplx, Ycplx);
2987  if (Mh == NULL)
2988  for (int i = 0; i < nloc; i++)
2989  Ycplx(i) += coef_mass*Xcplx(i);
2990  else
2991  Mh->MltAddVector(coef_mass, Xcplx, coef_stiff, Ycplx);
2992 
2993  for (int i = 0; i < this->n_; i++)
2994  Y(i) = Ycplx(local_col_numbers(i));
2995 #endif
2996  }
2997  else
2999  ::MltStiffness(coef_massb, coef_stiffb, X, Y);
3000  }
3001  }
3002 
3003 
3005  template<class T, class MatStiff, class MatMass>
3007  ::MltStiffness(const T& coef_mass, const T& coef_stiff,
3008  const Vector<Tcplx>& X, Vector<Tcplx>& Y)
3009  {
3010  if (Kh == NULL)
3011  this->PrintErrorInit();
3012  else
3013  {
3014  if (distributed)
3015  {
3016 #ifdef SELDON_WITH_MPI
3017  Vector<Tcplx> Xcplx(nloc), Ycplx(nloc);
3018  Xcplx.Zero();
3019  for (int i = 0; i < this->n_; i++)
3020  Xcplx(local_col_numbers(i)) = X(i);
3021 
3022  AssembleVector(Xcplx, MPI_SUM, *ProcSharingRows, *SharingRowNumbers,
3023  this->comm, nodl_scalar_, nb_unknowns_scal_, 17);
3024 
3025  Kh->MltVector(Xcplx, Ycplx);
3026  if (Mh == NULL)
3027  for (int i = 0; i < nloc; i++)
3028  Ycplx(i) += coef_mass*Xcplx(i);
3029  else
3030  Mh->MltAddVector(coef_mass, Xcplx, coef_stiff, Ycplx);
3031 
3032  for (int i = 0; i < this->n_; i++)
3033  Y(i) = Ycplx(local_col_numbers(i));
3034 #endif
3035  }
3036  else
3038  ::MltStiffness(coef_mass, coef_stiff, X, Y);
3039  }
3040  }
3041 
3042 
3044  template<class T, class MatStiff, class MatMass>
3047  {
3048  if (Kh == NULL)
3049  this->PrintErrorInit();
3050  else
3051  {
3052  if (distributed)
3053  {
3054 #ifdef SELDON_WITH_MPI
3055  Vector<Treal> Xcplx(nloc), Ycplx(nloc);
3056  Xcplx.Zero();
3057  for (int i = 0; i < this->n_; i++)
3058  Xcplx(local_col_numbers(i)) = X(i);
3059 
3060  AssembleVector(Xcplx, MPI_SUM, *ProcSharingRows, *SharingRowNumbers,
3061  this->comm, nodl_scalar_, nb_unknowns_scal_, 17);
3062 
3063  Kh->MltVector(trans, Xcplx, Ycplx);
3064 
3065  for (int i = 0; i < this->n_; i++)
3066  Y(i) = Ycplx(local_col_numbers(i));
3067 #endif
3068  }
3069  else
3070  Kh->MltVector(trans, X, Y);
3071  }
3072  }
3073 
3074 
3076  template<class T, class MatStiff, class MatMass>
3079  {
3080  if (Kh == NULL)
3081  this->PrintErrorInit();
3082  else
3083  {
3084  if (distributed)
3085  {
3086 #ifdef SELDON_WITH_MPI
3087  Vector<Tcplx> Xcplx(nloc), Ycplx(nloc);
3088  Xcplx.Zero();
3089  for (int i = 0; i < this->n_; i++)
3090  Xcplx(local_col_numbers(i)) = X(i);
3091 
3092  AssembleVector(Xcplx, MPI_SUM, *ProcSharingRows, *SharingRowNumbers,
3093  this->comm, nodl_scalar_, nb_unknowns_scal_, 17);
3094 
3095  Kh->MltVector(trans, Xcplx, Ycplx);
3096 
3097  for (int i = 0; i < this->n_; i++)
3098  Y(i) = Ycplx(local_col_numbers(i));
3099 #endif
3100  }
3101  else
3102  Kh->MltVector(trans, X, Y);
3103  }
3104  }
3105 
3106 
3109  template<class T, class MatStiff, class MatMass>
3111  ComputeAndFactorizeStiffnessMatrix(const Treal& a, const Treal& b, int which)
3112  {
3113  ComputeAndFactoRealMatrix(T(0), a, b, which);
3114  }
3115 
3116 
3119  template<class T, class MatStiff, class MatMass>
3121  ComputeAndFactoRealMatrix(const Tcplx&, const Treal& a, const Treal& b, int which)
3122  {
3123  cout << "Provide coefficients a and b of the same type as T" << endl;
3124  abort();
3125  }
3126 
3127 
3130  template<class T, class MatStiff, class MatMass>
3132  ComputeAndFactoRealMatrix(const Treal&, const Treal& a, const Treal& b, int which)
3133  {
3134  this->complex_system = false;
3135 
3136  if (Kh == NULL)
3137  this->PrintErrorInit();
3138 
3139  int rank_rci = 0;
3140 #ifdef SELDON_WITH_MPI
3141  MPI_Comm_rank(this->rci_comm, &rank_rci);
3142 #endif
3143 
3144  if ((this->print_level > 2) && (rank_rci == 0))
3145  mat_lu_real.ShowMessages();
3146 
3147  // retrieving symmetry of mass matrix
3148  bool sym_mh = true;
3149  if (Mh != NULL)
3150  {
3151  if (!IsSymmetricMatrix(*Mh))
3152  sym_mh = false;
3153  }
3154 
3155  T zero; SetComplexZero(zero);
3156 
3157  if (b == zero)
3158  {
3159  // only mass matrix must be factorized
3160  if (sym_mh)
3161  {
3162 #ifdef SELDON_WITH_MPI
3164  try
3165  {
3168 
3169  A.Init(K);
3170  }
3171  catch (const std::bad_cast&)
3172  {
3173  }
3174 #else
3176 #endif
3177  if (Mh == NULL)
3178  {
3179  A.Reallocate(nloc, nloc);
3180  A.SetIdentity();
3181  }
3182  else
3183  Copy(*Mh, A);
3184 
3185  Mlt(a, A);
3186  mat_lu_real.Factorize(A);
3187  }
3188  else
3189  {
3190 #ifdef SELDON_WITH_MPI
3192 #else
3194 #endif
3195  Copy(*Mh, A);
3196  Mlt(a, A);
3197  mat_lu_real.Factorize(A);
3198  }
3199  }
3200  else if (IsSymmetricMatrix(*Kh) && sym_mh)
3201  {
3202  // forming a M + b K and factorizing it when the result is symmetric
3203 #ifdef SELDON_WITH_MPI
3205 #else
3207 #endif
3208 
3209  Copy(*Kh, A);
3210  Mlt(b, A);
3211  if (a != zero)
3212  {
3213  if (Mh == NULL)
3214  {
3215 #ifdef SELDON_WITH_MPI
3216  if (distributed)
3217  {
3218  for (int i = 0; i < this->local_col_numbers.GetM(); i++)
3219  {
3220  int iloc = this->local_col_numbers(i);
3221  A.AddInteraction(iloc, iloc, a);
3222  }
3223  }
3224  else
3225  for (int i = 0; i < nloc; i++)
3226  A.AddInteraction(i, i, a);
3227 #else
3228  for (int i = 0; i < nloc; i++)
3229  A.AddInteraction(i, i, a);
3230 #endif
3231  }
3232  else
3233  Add(a, *Mh, A);
3234  }
3235 
3236  mat_lu_real.Factorize(A);
3237  }
3238  else
3239  {
3240  // forming a M + b K and factorizing it when the result is unsymmetric
3241 #ifdef SELDON_WITH_MPI
3243 #else
3245 #endif
3246  Copy(*Kh, A);
3247  Mlt(b, A);
3248  if (a != zero)
3249  {
3250  if (Mh == NULL)
3251  {
3252 #ifdef SELDON_WITH_MPI
3253  if (distributed)
3254  {
3255  for (int i = 0; i < this->local_col_numbers.GetM(); i++)
3256  {
3257  int iloc = this->local_col_numbers(i);
3258  A.AddInteraction(iloc, iloc, a);
3259  }
3260  }
3261  else
3262  for (int i = 0; i < nloc; i++)
3263  A.AddInteraction(i, i, a);
3264 #else
3265  for (int i = 0; i < nloc; i++)
3266  A.AddInteraction(i, i, a);
3267 #endif
3268  }
3269  else
3270  Add(a, *Mh, A);
3271  }
3272 
3273  mat_lu_real.Factorize(A);
3274  }
3275 
3276  mat_lu_real.HideMessages();
3277  }
3278 
3279 
3281  template<class T, class MatStiff, class MatMass>
3283  ComputeAndFactorizeStiffnessMatrix(const Tcplx& a, const Tcplx& b, int which)
3284  {
3285  this->complex_system = true;
3286  this->selected_part = which;
3287 
3288  if (Kh == NULL)
3289  this->PrintErrorInit();
3290 
3291  int rank_rci = 0;
3292 #ifdef SELDON_WITH_MPI
3293  MPI_Comm_rank(this->rci_comm, &rank_rci);
3294 #endif
3295 
3296  if ((this->print_level > 2) && (rank_rci == 0))
3297  mat_lu_cplx.ShowMessages();
3298 
3299  // retrieving symmetry of mass matrix
3300  bool sym_mh = true;
3301  if (Mh != NULL)
3302  {
3303  if (!IsSymmetricMatrix(*Mh))
3304  sym_mh = false;
3305  }
3306 
3307  Tcplx zero(0, 0);
3308 
3309  if (b == zero)
3310  {
3311  // only mass matrix must be factorized
3312  if (sym_mh)
3313  {
3314 #ifdef SELDON_WITH_MPI
3316  try
3317  {
3320 
3321  A.Init(K);
3322  }
3323  catch (const std::bad_cast&)
3324  {
3325  }
3326 #else
3328 #endif
3329  if (Mh == NULL)
3330  {
3331  A.Reallocate(nloc, nloc);
3332  A.SetIdentity();
3333  }
3334  else
3335  Copy(*Mh, A);
3336 
3337  Mlt(a, A);
3338  mat_lu_cplx.Factorize(A);
3339  }
3340  else
3341  {
3342 #ifdef SELDON_WITH_MPI
3344 #else
3346 #endif
3347  Copy(*Mh, A);
3348  Mlt(a, A);
3349  mat_lu_cplx.Factorize(A);
3350  }
3351  }
3352  else if (IsSymmetricMatrix(*Kh) && sym_mh)
3353  {
3354  // forming a M + b K
3355 #ifdef SELDON_WITH_MPI
3357 #else
3359 #endif
3360  Copy(*Kh, A);
3361  Mlt(b, A);
3362  if (a != zero)
3363  {
3364  if (Mh == NULL)
3365  {
3366 #ifdef SELDON_WITH_MPI
3367  if (distributed)
3368  {
3369  for (int i = 0; i < this->local_col_numbers.GetM(); i++)
3370  {
3371  int iloc = this->local_col_numbers(i);
3372  A.AddInteraction(iloc, iloc, a);
3373  }
3374  }
3375  else
3376  for (int i = 0; i < nloc; i++)
3377  A.AddInteraction(i, i, a);
3378 #else
3379  for (int i = 0; i < nloc; i++)
3380  A.AddInteraction(i, i, a);
3381 #endif
3382  }
3383  else
3384  Add(a, *Mh, A);
3385  }
3386 
3387  mat_lu_cplx.Factorize(A);
3388  }
3389  else
3390  {
3391  // forming a M + b K
3392 #ifdef SELDON_WITH_MPI
3394 #else
3396 #endif
3397  Copy(*Kh, A);
3398  Mlt(b, A);
3399  if (a != zero)
3400  {
3401  if (Mh == NULL)
3402  {
3403 #ifdef SELDON_WITH_MPI
3404  if (distributed)
3405  {
3406  for (int i = 0; i < this->local_col_numbers.GetM(); i++)
3407  {
3408  int iloc = this->local_col_numbers(i);
3409  A.AddInteraction(iloc, iloc, a);
3410  }
3411  }
3412  else
3413  for (int i = 0; i < nloc; i++)
3414  A.AddInteraction(i, i, a);
3415 #else
3416  for (int i = 0; i < nloc; i++)
3417  A.AddInteraction(i, i, a);
3418 #endif
3419  }
3420  else
3421  Add(a, *Mh, A);
3422  }
3423 
3424  mat_lu_cplx.Factorize(A);
3425  }
3426 
3427  mat_lu_cplx.HideMessages();
3428  }
3429 
3430 
3432  template<class T, class MatStiff, class MatMass>
3435  {
3436  ComputeSolution(SeldonNoTrans, X, Y);
3437  }
3438 
3439 
3441  template<class T, class MatStiff, class MatMass>
3444  {
3445  ComputeSolution(SeldonNoTrans, X, Y);
3446  }
3447 
3448 
3450  template<class T, class MatStiff, class MatMass>
3453  const Vector<Treal>& X, Vector<Treal>& Y)
3454  {
3455  if (this->complex_system)
3456  {
3457  if (this->selected_part == EigenProblem_Base<T>::COMPLEX_PART)
3458  {
3459  cout << "The result can not be a real vector" << endl;
3460  abort();
3461  }
3462 
3463  Vector<Tcplx> Xcplx(nloc);
3464  if (distributed)
3465  {
3466 #ifdef SELDON_WITH_MPI
3467  Xcplx.Zero();
3468  for (int i = 0; i < this->n_; i++)
3469  Xcplx(local_col_numbers(i)) = Tcplx(X(i), 0);
3470 
3471  // actually assemble is not needed since the direct solver
3472  // should extract only local values
3473  //AssembleVector(Xcplx, MPI_SUM, *ProcSharingRows, *SharingRowNumbers,
3474  // this->comm, nodl_scalar_, nb_unknowns_scal_, 16);
3475 #endif
3476  }
3477  else
3478  for (int i = 0; i < nloc; i++)
3479  Xcplx(i) = Tcplx(X(i), 0);
3480 
3481  mat_lu_cplx.Solve(transA, Xcplx, false);
3482 
3483  if (this->selected_part == EigenProblem_Base<T>::IMAG_PART)
3484  {
3485  if (distributed)
3486  {
3487 #ifdef SELDON_WITH_MPI
3488  for (int i = 0; i < this->n_; i++)
3489  Y(i) = imag(Xcplx(local_col_numbers(i)));
3490 #endif
3491  }
3492  else
3493  for (int i = 0; i < nloc; i++)
3494  Y(i) = imag(Xcplx(i));
3495  }
3496  else
3497  {
3498  if (distributed)
3499  {
3500 #ifdef SELDON_WITH_MPI
3501  for (int i = 0; i < this->n_; i++)
3502  Y(i) = real(Xcplx(local_col_numbers(i)));
3503 #endif
3504  }
3505  else
3506  for (int i = 0; i < this->n_; i++)
3507  Y(i) = real(Xcplx(i));
3508  }
3509  }
3510  else
3511  {
3512  Vector<Treal> Xreal(nloc);
3513  if (distributed)
3514  {
3515 #ifdef SELDON_WITH_MPI
3516  Xreal.Zero();
3517  for (int i = 0; i < this->n_; i++)
3518  Xreal(local_col_numbers(i)) = X(i);
3519 
3520  // actually assemble is not needed since the direct solver
3521  // should extract only local values
3522  // AssembleVector(Xreal, MPI_SUM, *ProcSharingRows, *SharingRowNumbers,
3523  // this->comm, nodl_scalar_, nb_unknowns_scal_, 16);
3524 #endif
3525  }
3526  else
3527  Xreal = X;
3528 
3529  mat_lu_real.Solve(transA, Xreal, false);
3530 
3531  if (distributed)
3532  {
3533 #ifdef SELDON_WITH_MPI
3534  for (int i = 0; i < this->n_; i++)
3535  Y(i) = Xreal(local_col_numbers(i));
3536 #endif
3537  }
3538  else
3539  Copy(Xreal, Y);
3540  }
3541  }
3542 
3543 
3545  template<class T, class MatStiff, class MatMass>
3548  const Vector<Tcplx>& X, Vector<Tcplx>& Y)
3549  {
3550  if (this->complex_system)
3551  {
3552  if (this->selected_part == EigenProblem_Base<T>::COMPLEX_PART)
3553  {
3554  Vector<Tcplx> Xcplx(nloc);
3555  if (distributed)
3556  {
3557 #ifdef SELDON_WITH_MPI
3558  Xcplx.Zero();
3559  for (int i = 0; i < this->n_; i++)
3560  Xcplx(local_col_numbers(i)) = X(i);
3561 
3562  // actually assemble is not needed since the direct solver
3563  // should extract only original values
3564  //AssembleVector(Xcplx, MPI_SUM, *ProcSharingRows, *SharingRowNumbers,
3565  // this->comm, nodl_scalar_, nb_unknowns_scal_, 16);
3566 #endif
3567  }
3568  else
3569  Xcplx = X;
3570 
3571  mat_lu_cplx.Solve(transA, Xcplx, false);
3572 
3573  if (distributed)
3574  {
3575 #ifdef SELDON_WITH_MPI
3576  for (int i = 0; i < this->n_; i++)
3577  Y(i) = Xcplx(local_col_numbers(i));
3578 #endif
3579  }
3580  else
3581  Copy(Xcplx, Y);
3582  }
3583  else
3584  {
3585  cout << "not implemented" << endl;
3586  abort();
3587  }
3588  }
3589  else
3590  {
3591  cout << "not implemented" << endl;
3592  abort();
3593  //Copy(X, Y);
3594  //mat_lu_real.Solve(transA, Y);
3595  }
3596  }
3597 
3598 
3600  template<class T, class MatStiff, class MatMass>
3603  {
3604  if (distributed)
3605  {
3606 #ifdef SELDON_WITH_MPI
3607  this->AssembleEigenvectors(eigen_vec, local_col_numbers, ProcSharingRows,
3608  SharingRowNumbers, nloc, nodl_scalar_, nb_unknowns_scal_);
3609 #endif
3610  }
3611  }
3612 
3614  template<class T, class MatStiff, class MatMass>
3616  {
3617  mat_lu_real.Clear();
3618  mat_lu_cplx.Clear();
3619  chol_facto_mass_matrix.Clear();
3620  Xchol_real.Clear();
3621  Xchol_imag.Clear();
3622  }
3623 
3624 
3627  {
3628 #ifdef SELDON_WITH_ARPACK
3629  return ARPACK;
3630 #endif
3631 
3632 #ifdef SELDON_WITH_ANASAZI
3633  return ANASAZI;
3634 #endif
3635 
3636 #ifdef SELDON_WITH_FEAST
3637  return FEAST;
3638 #endif
3639 
3640 #ifdef SELDON_WITH_SLEPC
3641  return SLEPC;
3642 #endif
3643 
3644  return -1;
3645  }
3646 
3647 
3650  {
3651 #ifdef SELDON_WITH_FEAST
3652  return FEAST;
3653 #endif
3654 
3655 #ifdef SELDON_WITH_SLEPC
3656  return SLEPC;
3657 #endif
3658 
3659  return -1;
3660  }
3661 
3662 
3665  {
3666 #ifdef SELDON_WITH_SLEPC
3667  return SLEPC;
3668 #endif
3669 
3670  return -1;
3671  }
3672 
3673 
3674  template<class T, class Prop, class Storage>
3675  void GetEigenvaluesEigenvectors(EigenProblem_Base<T>& var_eig,
3676  Vector<T>& lambda, Vector<T>& lambda_imag,
3677  Matrix<T, Prop, Storage>& eigen_vec,
3678  int type_solver)
3679  {
3680  if (type_solver == TypeEigenvalueSolver::DEFAULT)
3682 
3683  if (type_solver == TypeEigenvalueSolver::ARPACK)
3684  {
3685 #ifdef SELDON_WITH_ARPACK
3686  T zero; SetComplexZero(zero);
3687  Matrix<T, General, ColMajor> eigen_old;
3688  FindEigenvaluesArpack(var_eig, lambda, lambda_imag, eigen_old);
3689 
3690  // eigenvalues are sorted by ascending order
3691  SortEigenvalues(lambda, lambda_imag, eigen_old,
3692  eigen_vec, var_eig.LARGE_EIGENVALUES,
3693  var_eig.GetTypeSorting(), zero, zero);
3694 #else
3695  cout << "Recompile with Arpack" << endl;
3696  abort();
3697 #endif
3698  }
3699  else if (type_solver == TypeEigenvalueSolver::ANASAZI)
3700  {
3701 #ifdef SELDON_WITH_ANASAZI
3702  T zero; SetComplexZero(zero);
3703  Matrix<T, General, ColMajor> eigen_old;
3704  FindEigenvaluesAnasazi(var_eig, lambda, lambda_imag, eigen_old);
3705 
3706  // eigenvalues are sorted by ascending order
3707  SortEigenvalues(lambda, lambda_imag, eigen_old,
3708  eigen_vec, var_eig.LARGE_EIGENVALUES,
3709  var_eig.GetTypeSorting(), zero, zero);
3710 #else
3711  cout << "Recompile with Anasazi" << endl;
3712  abort();
3713 #endif
3714  }
3715  else if (type_solver == TypeEigenvalueSolver::FEAST)
3716  {
3717 #ifdef SELDON_WITH_FEAST
3718  T zero; SetComplexZero(zero);
3719  Matrix<T, General, ColMajor> eigen_old;
3720  FindEigenvaluesFeast(var_eig, lambda, lambda_imag, eigen_old);
3721 
3722  // eigenvalues are sorted by ascending order
3723  SortEigenvalues(lambda, lambda_imag, eigen_old,
3724  eigen_vec, var_eig.LARGE_EIGENVALUES,
3725  var_eig.GetTypeSorting(), zero, zero);
3726 #else
3727  cout << "Recompile with MKL or Feast" << endl;
3728  abort();
3729 #endif
3730  }
3731  else if (type_solver == TypeEigenvalueSolver::SLEPC)
3732  {
3733 #ifdef SELDON_WITH_SLEPC
3734  T zero; SetComplexZero(zero);
3735  Matrix<T, General, ColMajor> eigen_old;
3736  FindEigenvaluesSlepc(var_eig, lambda, lambda_imag, eigen_old);
3737 
3738  // eigenvalues are sorted by ascending order
3739  SortEigenvalues(lambda, lambda_imag, eigen_old,
3740  eigen_vec, var_eig.LARGE_EIGENVALUES,
3741  var_eig.GetTypeSorting(), zero, zero);
3742 #else
3743  cout << "Recompile with Slepc" << endl;
3744  abort();
3745 #endif
3746  }
3747  else
3748  {
3749  cout << "Recompile with eigenvalue solver" << endl;
3750  abort();
3751  }
3752 
3753  }
3754 }
3755 
3756 #define SELDON_FILE_VIRTUAL_EIGENVALUE_SOLVER_CXX
3757 #endif
Seldon::GeneralEigenProblem_Base::GetM
int GetM() const
returns number of rows
Definition: VirtualEigenvalueSolver.cxx:359
Seldon::GeneralEigenProblem_Base::GetNbArnoldiVectors
int GetNbArnoldiVectors() const
returns the number of Arnoldi vectors to use
Definition: VirtualEigenvalueSolver.cxx:344
Seldon::EigenProblem_Base< T >::PrintErrorInit
void PrintErrorInit() const
prints error of initialization and aborts program
Definition: EigenvalueSolver.cxx:538
Seldon::EigenProblem_Base::GetTypeSpectrum
int GetTypeSpectrum() const
returns the spectrum desired (large, small eigenvalues, etc)
Definition: EigenvalueSolver.cxx:253
Seldon::AnasaziParam::nb_blocks
int nb_blocks
number of blocks for blocked solvers
Definition: VirtualEigenvalueSolver.hxx:40
Seldon::DenseEigenProblem
computation of a few eigenvalues for dense matrices
Definition: EigenvalueSolver.hxx:330
Seldon::DenseEigenProblem::mat_lu_real
Matrix< Treal, Prop, Storage > mat_lu_real
LU factorisation of a real matrix.
Definition: VirtualEigenvalueSolver.hxx:688
Seldon::AnasaziParam::SetEigensolverType
void SetEigensolverType(int type)
sets the solver used in Anasazi
Definition: VirtualEigenvalueSolver.cxx:70
Seldon::SparseEigenProblem::MltStiffness
void MltStiffness(const Vector< Treal > &X, Vector< Treal > &Y)
multiplication by stiffness matrix
Definition: VirtualEigenvalueSolver.cxx:2899
Seldon::SeldonTranspose
Definition: MatrixFlag.hxx:32
Seldon::GeneralEigenProblem_Base::GeneralEigenProblem_Base
GeneralEigenProblem_Base()
default constructor
Definition: VirtualEigenvalueSolver.cxx:172
Seldon::AnasaziParam::type_solver
int type_solver
which solver ?
Definition: VirtualEigenvalueSolver.hxx:46
Seldon::FeastParam::ratio_ellipse
double ratio_ellipse
parameters for an ellipse
Definition: VirtualEigenvalueSolver.hxx:184
Seldon::EigenProblem_Base::EigenProblem_Base
EigenProblem_Base()
default constructor
Definition: EigenvalueSolver.cxx:15
Seldon::DistributedMatrix_Base::Init
void Init(int n, IVect *, IVect *, IVect *, int, int, IVect *, Vector< IVect > *, const MPI_Comm &)
Initialisation of pointers.
Definition: DistributedMatrix.cxx:1750
Seldon::GeneralEigenProblem::SetUserComparisonClass
void SetUserComparisonClass(EigenvalueComparisonClass< T > *ev)
sets the class where two eigenvalues can be compared
Definition: VirtualEigenvalueSolver.cxx:573
Seldon::VirtualEigenProblem::MltStiffness
void MltStiffness(const Vector< Treal > &X, Vector< Treal > &Y)
matrix vector product with stifness matrix Y = K X
Definition: VirtualEigenvalueSolver.cxx:1345
Seldon::GeneralEigenProblem::GetComplexShift
void GetComplexShift(const Treal &, const Treal &, Tcplx &) const
forms the complex shift from real and imaginary part
Definition: VirtualEigenvalueSolver.cxx:522
Seldon::EigenProblem_Base::eigenvalue_computation_mode
int eigenvalue_computation_mode
mode used to find eigenvalues (regular, shifted, Cayley, etc)
Definition: EigenvalueSolver.hxx:68
Seldon::Copy
void Copy(const DistributedMatrix< complex< T >, Prop1, Storage1, Allocator1 > &A, DistributedMatrix< T, Prop2, Storage2, Allocator2 > &B)
converts a distributed matrix to another one
Definition: DistributedMatrixInline.cxx:344
Seldon::AnasaziParam::restart_number
int restart_number
restart parameter for blocked solvers
Definition: VirtualEigenvalueSolver.hxx:43
Seldon::SparseEigenProblem::FactorizeCholeskyMass
void FactorizeCholeskyMass()
computes Cholesky factorisation of M from matrix M
Definition: EigenvalueSolver.cxx:1481
Seldon::GeneralEigenProblem_Base::type_sort_eigenvalues
int type_sort_eigenvalues
large eigenvalues because of their real part, imaginary part or magnitude ?
Definition: VirtualEigenvalueSolver.hxx:264
Seldon::EigenProblem_Base::GetTypeSorting
int GetTypeSorting() const
returns how eigenvalues are sorted (real, imaginary part or modulus)
Definition: EigenvalueSolver.cxx:261
Seldon::SlepcParam
Parameters for Slepc package.
Definition: VirtualEigenvalueSolver.hxx:64
Seldon::Vector
Definition: SeldonHeader.hxx:207
Seldon::FeastParam::SetCircleSpectrum
void SetCircleSpectrum(const complex< double > &z, double r)
sets a circle where eigenvalues are searched
Definition: VirtualEigenvalueSolver.cxx:150
Seldon::GeneralEigenProblem_Base::GetTypeSpectrum
int GetTypeSpectrum() const
returns the spectrum desired (large, small eigenvalues, etc)
Definition: VirtualEigenvalueSolver.cxx:294
Seldon::GeneralEigenProblem_Base::GetNbLinearSolves
int GetNbLinearSolves() const
returns the number of linear solves
Definition: VirtualEigenvalueSolver.cxx:408
Seldon::IsSymmetricMatrix
bool IsSymmetricMatrix(const Matrix< T, Prop, Storage, Allocator > &A)
returns true if the matrix is symmetric
Definition: Functions_BaseInline.cxx:778
Seldon::SparseEigenProblem::Clear
void Clear()
clears memory used by the object
Definition: EigenvalueSolver.cxx:1913
Seldon::EigenProblem_Base< T >::GetComputationalMode
int GetComputationalMode() const
returns the spectral transformation used for evaluation of eigenvalues
Definition: EigenvalueSolver.cxx:133
Seldon::SortEigenvalues
void SortEigenvalues(Vector< T > &lambda_r, Vector< T > &lambda_i, Matrix< T, General, Storage1, Alloc1 > &eigen_old, Matrix< T, General, Storage2, Alloc2 > &eigen_new, int type_spectrum, int type_sort, const T &shift_r, const T &shift_i)
sorting eigenvalues
Definition: EigenvalueSolver.cxx:1040
Seldon::EigenProblem_Base::MltStiffness
void MltStiffness(const Vector< T > &X, Vector< T > &Y)
matrix vector product with stifness matrix Y = K X
Definition: EigenvalueSolver.cxx:709
Seldon::EigenProblem_Base< T >::ComputeStiffnessMatrix
void ComputeStiffnessMatrix()
computation of stiffness matrix K
Definition: EigenvalueSolver.cxx:691
Seldon::Matrix
Definition: SeldonHeader.hxx:226
Seldon::FeastParam::nb_points_quadrature
int nb_points_quadrature
number of points in the contour
Definition: VirtualEigenvalueSolver.hxx:172
Seldon::AnasaziParam::GetNbMaximumRestarts
int GetNbMaximumRestarts() const
returns the restart parameter used in blocked solvers
Definition: VirtualEigenvalueSolver.cxx:42
Seldon::EigenProblem_Base< T >::ComputeMassMatrix
void ComputeMassMatrix()
computation of mass matrix M
Definition: EigenvalueSolver.cxx:663
Seldon::GeneralEigenProblem_Base::nb_prod
int nb_prod
number of matrix-vector products
Definition: VirtualEigenvalueSolver.hxx:277
Seldon::FindEigenvaluesAnasazi
void FindEigenvaluesAnasazi(EigenProblem &var, Vector< T, VectFull, Allocator1 > &eigen_values, Vector< T, VectFull, Allocator2 > &lambda_imag, Matrix< T, General, ColMajor, Allocator3 > &eigen_vectors)
computation of eigenvalues and related eigenvectors
Definition: Anasazi.cxx:244
Seldon::GeneralEigenProblem_Base::nb_linear_solves
int nb_linear_solves
number of linear solves
Definition: VirtualEigenvalueSolver.hxx:273
Seldon::GeneralEigenProblem_Base::GetNbMaximumIterations
int GetNbMaximumIterations() const
returns the maximal number of iterations allowed for the iterative algorithm
Definition: VirtualEigenvalueSolver.cxx:329
Seldon::SparseEigenProblem::MltCholeskyMass
void MltCholeskyMass(const TransStatus &transA, Vector< T0 > &X)
computes L X or L^T x if M = L L^T
Definition: EigenvalueSolver.cxx:1526
Seldon::DenseEigenProblem::Mh
Matrix< Tmass, PropM, StorageM > * Mh
mass matrix
Definition: VirtualEigenvalueSolver.hxx:694
Seldon::GeneralEigenProblem::SetImagShiftValue
void SetImagShiftValue(const T &)
Sets the imaginary part of shift value.
Definition: VirtualEigenvalueSolver.cxx:513
Seldon::GeneralEigenProblem_Base::SetPrintLevel
void SetPrintLevel(int lvl)
sets the level of verbosity
Definition: VirtualEigenvalueSolver.cxx:387
Seldon::SparseEigenProblem::ComputeSolution
void ComputeSolution(const Vector< T0 > &X, Vector< T0 > &Y)
solves (a M + b K) Y = X with stored factorization
Definition: EigenvalueSolver.cxx:1845
Seldon::DenseEigenProblem::Kh
Matrix< Tstiff, Prop, Storage > * Kh
stiffness matrix
Definition: VirtualEigenvalueSolver.hxx:697
Seldon::FeastParam::evaluate_number_eigenval
bool evaluate_number_eigenval
if true, we want to estimate the number of eigenvalues
Definition: VirtualEigenvalueSolver.hxx:169
Seldon::GeneralEigenProblem::GetShiftValue
T GetShiftValue() const
returns the shift value used
Definition: VirtualEigenvalueSolver.cxx:483
Seldon::DistributedMatrix_Base
Base class for distributed matrix over all the processors.
Definition: DistributedMatrix.hxx:103
Seldon::GeneralEigenProblem::SetTypeSpectrum
void SetTypeSpectrum(int type, const T &val, int type_sort=SORTED_MODULUS)
sets which eigenvalues are searched
Definition: VirtualEigenvalueSolver.cxx:544
Seldon::FeastParam::GetLowerBoundInterval
double GetLowerBoundInterval() const
returns lower bound of the interval where eigenvalues are searched
Definition: VirtualEigenvalueSolver.cxx:128
Seldon::TypeEigenvalueSolver::GetDefaultSolver
static int GetDefaultSolver()
returns the default eigenvalue solver (linear eigenproblem)
Definition: EigenvalueSolver.cxx:1936
Seldon::VirtualMatrix::GetM
int GetM() const
Returns the number of rows.
Definition: Matrix_BaseInline.cxx:69
Seldon::EigenProblem_Base< T >::SetNbAdditionalEigenvalues
void SetNbAdditionalEigenvalues(int n)
sets the number of additional eigenvalues
Definition: EigenvalueSolver.cxx:245
Seldon::AnasaziParam::GetNbBlocks
int GetNbBlocks() const
returns the number of blocks used in blocked solvers
Definition: VirtualEigenvalueSolver.cxx:28
Seldon::EigenProblem_Base::SolveCholeskyMass
void SolveCholeskyMass(const TransStatus &transA, Vector< T > &X)
computation of L^-1 X or L^-T x if M = L L^T
Definition: EigenvalueSolver.cxx:819
Seldon::AnasaziParam::GetEigensolverType
int GetEigensolverType() const
returns the solver used in Anasazi
Definition: VirtualEigenvalueSolver.cxx:63
Seldon::GeneralEigenProblem_Base::GetRankCommunicator
int GetRankCommunicator() const
returns rank for the solver communicator
Definition: VirtualEigenvalueSolver.cxx:254
Seldon::DenseEigenProblem::mat_lu_cplx
Matrix< Tcplx, Prop, Storage > mat_lu_cplx
LU factorisation of a complex matrix.
Definition: VirtualEigenvalueSolver.hxx:691
Seldon::FeastParam::emin_interval
double emin_interval
interval where eigenvalues are searched (real symmetric or hermitian)
Definition: VirtualEigenvalueSolver.hxx:178
Seldon::SparseEigenProblem::ComputeAndFactorizeStiffnessMatrix
void ComputeAndFactorizeStiffnessMatrix(const T &a, const T &b)
computes and factorizes a M + b K where M is the mass matrix and K the stiffness matrix
Definition: EigenvalueSolver.cxx:1635
Seldon::GeneralEigenProblem_Base::IncrementProdMatVect
void IncrementProdMatVect()
increment of the number of matrix vector products
Definition: VirtualEigenvalueSolver.cxx:401
Seldon::SparseEigenProblem::MltMass
void MltMass(const Vector< Treal > &X, Vector< Treal > &Y)
multiplication by mass matrix
Definition: VirtualEigenvalueSolver.cxx:2772
Seldon::FeastParam::center_spectrum
complex< double > center_spectrum
disk where eigenvalues are searched (non-symmetric)
Definition: VirtualEigenvalueSolver.hxx:181
Seldon::VirtualEigenProblem::Clear
void Clear()
memory release
Definition: VirtualEigenvalueSolver.cxx:1449
Seldon::EigenvalueComparisonClass
base class for setting comparison between eigenvalues
Definition: VirtualEigenvalueSolver.hxx:228
Seldon::General
Definition: Properties.hxx:26
Seldon::AnasaziParam::GetOrthoManager
int GetOrthoManager() const
returns orthogonalization manager set in Anasazi
Definition: VirtualEigenvalueSolver.cxx:56
Seldon::EigenProblem_Base::MltMass
void MltMass(const Vector< T > &X, Vector< T > &Y)
matrix vector product with mass matrix Y = M X
Definition: EigenvalueSolver.cxx:672
Seldon::AnasaziParam
Parameters for Anasazi package.
Definition: VirtualEigenvalueSolver.hxx:21
Seldon::SlepcParam::type_solver
int type_solver
which solver ?
Definition: VirtualEigenvalueSolver.hxx:68
Seldon::GetLU
void GetLU(Matrix< T0, Prop0, Storage0, Allocator0 > &A)
Returns the LU factorization of a matrix.
Definition: Functions_Matrix.cxx:2073
Seldon::GeneralEigenProblem_Base::IncrementLinearSolves
void IncrementLinearSolves()
increments the number of linear solves
Definition: VirtualEigenvalueSolver.cxx:415
Seldon::FeastParam::FeastParam
FeastParam()
default constructor
Definition: VirtualEigenvalueSolver.cxx:114
Seldon::EigenProblem_Base< T >::DiagonalMass
bool DiagonalMass() const
returns true if the mass matrix is diagonal
Definition: EigenvalueSolver.cxx:412
Seldon::TypeEigenvalueSolver::GetDefaultPolynomialSolver
static int GetDefaultPolynomialSolver()
returns the default eigenvalue solver (polynomial eigenproblem)
Definition: VirtualEigenvalueSolver.cxx:3649
Seldon::EigenProblem_Base::GetImagShiftValue
T GetImagShiftValue() const
returns the imaginary part of shift value used
Definition: EigenvalueSolver.cxx:288
Seldon::GeneralEigenProblem_Base::~GeneralEigenProblem_Base
virtual ~GeneralEigenProblem_Base()
destructor
Definition: VirtualEigenvalueSolver.cxx:202
Seldon::GeneralEigenProblem_Base::GetPrintLevel
int GetPrintLevel() const
returns level of verbosity
Definition: VirtualEigenvalueSolver.cxx:380
Seldon::GeneralEigenProblem_Base::GetNbAskedEigenvalues
int GetNbAskedEigenvalues() const
returns the number of eigenvalues asked by the user
Definition: VirtualEigenvalueSolver.cxx:280
Seldon::FeastParam::SetIntervalSpectrum
void SetIntervalSpectrum(double, double)
sets the interval where eigenvalues are searched
Definition: VirtualEigenvalueSolver.cxx:142
Seldon::EigenProblem_Base
Base class to solve an eigenvalue problem.
Definition: EigenvalueSolver.hxx:18
Seldon::SparseEigenProblem::ComputeAndFactoRealMatrix
void ComputeAndFactoRealMatrix(const Treal &, const Treal &a, const Treal &b, int which)
computes and factorizes a M + b K where M is the mass matrix and K the stiffness matrix
Definition: VirtualEigenvalueSolver.cxx:3132
Seldon::FeastParam::type_integration
int type_integration
Method of integration.
Definition: VirtualEigenvalueSolver.hxx:175
Seldon::GeneralEigenProblem::GeneralEigenProblem
GeneralEigenProblem()
default constructor
Definition: VirtualEigenvalueSolver.cxx:469
Seldon::TypeEigenvalueSolver::GetDefaultNonLinearSolver
static int GetDefaultNonLinearSolver()
returns the default eigenvalue solver (non-linear eigenproblem)
Definition: VirtualEigenvalueSolver.cxx:3664
Seldon::DistributedMatrix
matrix distributed over all the processors
Definition: DistributedMatrix.hxx:506
Seldon::GeneralEigenProblem_Base::n_
int n_
size of the problem
Definition: VirtualEigenvalueSolver.hxx:280
Seldon::GeneralEigenProblem_Base::GetN
int GetN() const
returns number of columns
Definition: VirtualEigenvalueSolver.cxx:373
Seldon::AnasaziParam::SetNbBlocks
void SetNbBlocks(int)
returns the number of blocks used in blocked solvers
Definition: VirtualEigenvalueSolver.cxx:35
Seldon::EigenProblem_Base< T >::GetNbAdditionalEigenvalues
int GetNbAdditionalEigenvalues() const
returns the additional number of eigenvalues
Definition: EigenvalueSolver.cxx:157
Seldon::EigenProblem_Base< T >::UseCholeskyFactoForMass
bool UseCholeskyFactoForMass() const
returns true if Cholesky factorisation has to be used for mass matrix
Definition: EigenvalueSolver.cxx:396
Seldon::FeastParam::SetEllipseSpectrum
void SetEllipseSpectrum(const complex< double > &z, double r, double ratio, double teta)
sets an ellipse where eigenvalues are searched
Definition: VirtualEigenvalueSolver.cxx:158
Seldon::SparseEigenProblem::DistributeEigenvectors
void DistributeEigenvectors(Matrix< T, General, ColMajor > &eigen_vec)
changes final eigenvectors if needed
Definition: VirtualEigenvalueSolver.cxx:3602
Seldon::GeneralEigenProblem_Base::automatic_selection_arnoldi_vectors
bool automatic_selection_arnoldi_vectors
if true nb_arnoldi_vectors is automatically computed
Definition: VirtualEigenvalueSolver.hxx:258
Seldon::EigenProblem_Base< T >::SetDiagonalMass
void SetDiagonalMass(bool diag=true)
indicates that the mass matrix is diagonal
Definition: EigenvalueSolver.cxx:404
Seldon::GeneralEigenProblem::SetShiftValue
void SetShiftValue(const T &)
Sets the real part of shift value.
Definition: VirtualEigenvalueSolver.cxx:505
Seldon::GeneralEigenProblem_Base::SetNbMaximumIterations
void SetNbMaximumIterations(int n)
sets the maximal number of iterations allowed for the iterative algorithm
Definition: VirtualEigenvalueSolver.cxx:322
Seldon::FindEigenvaluesArpack
void FindEigenvaluesArpack(EigenProblem &var, Vector< T, VectFull, Allocator1 > &eigen_values, Vector< T, VectFull, Allocator2 > &lambda_imag, Matrix< T, General, ColMajor, Allocator3 > &eigen_vectors)
computation of eigenvalues and related eigenvectors
Definition: Arpack.cxx:41
Seldon::GeneralEigenProblem_Base::nb_maximum_iterations
int nb_maximum_iterations
Maximal number of iterations.
Definition: VirtualEigenvalueSolver.hxx:270
Seldon::GeneralEigenProblem_Base::GetStoppingCriterion
double GetStoppingCriterion() const
returns the stopping criterion
Definition: VirtualEigenvalueSolver.cxx:315
Seldon::VirtualEigenProblem
base class for eigenvalue problems
Definition: VirtualEigenvalueSolver.hxx:595
Seldon::SparseEigenProblem::SolveCholeskyMass
void SolveCholeskyMass(const TransStatus &transA, Vector< T0 > &X)
computes L^-1 X or L^-T x if M = L L^T
Definition: EigenvalueSolver.cxx:1536
Seldon::AnasaziParam::AnasaziParam
AnasaziParam()
default constructor
Definition: VirtualEigenvalueSolver.cxx:18
Seldon
Seldon namespace.
Definition: Array.cxx:24
Seldon::GeneralEigenProblem_Base::nb_eigenvalues_wanted
int nb_eigenvalues_wanted
number of eigenvalues to be computed
Definition: VirtualEigenvalueSolver.hxx:252
Seldon::SlepcParam::SlepcParam
SlepcParam()
Default constructor.
Definition: VirtualEigenvalueSolver.cxx:82
Seldon::GeneralEigenProblem_Base::Init
void Init(int n)
initialisation of the size of the eigenvalue problem
Definition: VirtualEigenvalueSolver.cxx:434
Seldon::GeneralEigenProblem_Base::GetGlobalM
int GetGlobalM() const
returns global number of rows
Definition: VirtualEigenvalueSolver.cxx:366
Seldon::GeneralEigenProblem::GetImagShiftValue
T GetImagShiftValue() const
returns the imaginary part of shift value used
Definition: VirtualEigenvalueSolver.cxx:497
Seldon::EigenProblem_Base< T >::ComputeMassForCholesky
void ComputeMassForCholesky()
computation of mass matrix
Definition: EigenvalueSolver.cxx:654
Seldon::GeneralEigenProblem_Base::GetNbMatrixVectorProducts
int GetNbMatrixVectorProducts() const
returns the number of matrix-vector products performed since last call to Init
Definition: VirtualEigenvalueSolver.cxx:337
Seldon::AnasaziParam::ortho_manager
int ortho_manager
orthogonalization manager
Definition: VirtualEigenvalueSolver.hxx:37
Seldon::ApplyScalingEigenvec
void ApplyScalingEigenvec(EigenPb &var, Vector1 &eigen_values, Vector1 &lambda_imag, Matrix1 &eigen_vectors, const T0 &shiftr, const T0 &shifti)
modification of eigenvectors to take into account scaling by mass matrix
Definition: EigenvalueSolver.cxx:846
Seldon::GeneralEigenProblem_Base::nb_arnoldi_vectors
int nb_arnoldi_vectors
number of Arnoldi vectors
Definition: VirtualEigenvalueSolver.hxx:255
Seldon::GeneralEigenProblem_Base::GetGlobalRankCommunicator
int GetGlobalRankCommunicator() const
returns rank for the global communicator
Definition: VirtualEigenvalueSolver.cxx:267
Seldon::GeneralEigenProblem
class for solving a general eigenproblem with parameter T (double or complex)
Definition: VirtualEigenvalueSolver.hxx:349
Seldon::FeastParam
parameters for Feast package
Definition: VirtualEigenvalueSolver.hxx:165
Seldon::GeneralEigenProblem_Base::type_spectrum_wanted
int type_spectrum_wanted
which spectrum ? Near from Zero ? Near from Infinity ? or near from a value ?
Definition: VirtualEigenvalueSolver.hxx:261
Seldon::GeneralEigenProblem::DistributeEigenvectors
virtual void DistributeEigenvectors(Matrix< T, General, ColMajor > &eigen_vec)
changes final eigenvectors if needed
Definition: VirtualEigenvalueSolver.cxx:737
Seldon::FeastParam::GetUpperBoundInterval
double GetUpperBoundInterval() const
returns upper bound of the interval where eigenvalues are searched
Definition: VirtualEigenvalueSolver.cxx:135
Seldon::EigenProblem_Base< T >::SetComputationalMode
void SetComputationalMode(int mode)
sets the spectral transformation used for evaluation of eigenvalues
Definition: EigenvalueSolver.cxx:141
Seldon::GeneralEigenProblem_Base::SetNbAskedEigenvalues
void SetNbAskedEigenvalues(int n)
sets the number of eigenvalues to compute
Definition: VirtualEigenvalueSolver.cxx:287
Seldon::AnasaziParam::SetNbMaximumRestarts
void SetNbMaximumRestarts(int)
sets the restart parameter used in blocked solvers
Definition: VirtualEigenvalueSolver.cxx:49
Seldon::SparseEigenProblem::SelectCholeskySolver
void SelectCholeskySolver(int type)
sets Cholesky solver to use
Definition: EigenvalueSolver.cxx:1472
Seldon::SetComplexReal
void SetComplexReal(int n, std::complex< T > &number)
Sets a complex number to (n, 0).
Definition: CommonInline.cxx:234
Seldon::GeneralEigenProblem_Base::SetStoppingCriterion
void SetStoppingCriterion(double eps)
modifies the stopping critertion
Definition: VirtualEigenvalueSolver.cxx:308
Seldon::VirtualMatrix
Abstract base class for all matrices.
Definition: Matrix_Base.hxx:42
Seldon::GeneralEigenProblem_Base::SetNbArnoldiVectors
void SetNbArnoldiVectors(int n)
sets the number of Arnoldi vectors to use
Definition: VirtualEigenvalueSolver.cxx:351
Seldon::SparseEigenProblem::ComputeDiagonalMass
void ComputeDiagonalMass()
computation of diagonal of mass matrix
Definition: VirtualEigenvalueSolver.cxx:2506
Seldon::GeneralEigenProblem_Base::GetTypeSorting
int GetTypeSorting() const
returns how eigenvalues are sorted (real, imaginary part or modulus)
Definition: VirtualEigenvalueSolver.cxx:301
Seldon::GeneralEigenProblem_Base::stopping_criterion
double stopping_criterion
threshold for Arpack's iterative process
Definition: VirtualEigenvalueSolver.hxx:267
Seldon::ColMajor
Definition: Storage.hxx:33