19 #ifndef SELDON_FILE_ARPACK_CXX
32 #ifdef SELDON_WITH_VIRTUAL
35 Vector<T>& eigen_values,
36 Vector<T>& lambda_imag,
37 Matrix<T, General, ColMajor>& eigen_vectors)
39 template<
class EigenProblem,
class T,
class Allocator1,
40 class Allocator2,
class Allocator3>
48 int ido = 0, n = var.GetM();
51 switch (var.GetTypeSorting())
58 if (var.GetTypeSpectrum() == var.SMALL_EIGENVALUES)
60 switch (var.GetTypeSorting())
70 double tol = var.GetStoppingCriterion();
73 int ncv = var.GetNbArnoldiVectors();
77 IVect iparam(11), ipntr(14);
78 iparam.Fill(0); ipntr.Fill(0);
79 int ishift = 1, nb_max_iter = var.GetNbMaximumIterations();
81 if (var.IsSymmetricProblem())
87 iparam(2) = nb_max_iter;
90 int lworkl = 3*ncv*ncv + 6*ncv, info(0);
94 T shiftr = var.GetShiftValue(), shifti = var.GetImagShiftValue();
96 #ifdef SELDON_WITH_VIRTUAL
97 typename ClassComplexType<T>::Tcplx shift_complex, cone;
99 var.GetComplexShift(shiftr, shifti, shift_complex);
103 SetComplexZero(zero);
107 int print_level = var.GetPrintLevel();
109 #ifdef SELDON_WITH_MPI
110 MPI_Comm& comm = var.GetCommunicator();
111 int comm_f = MPI_Comm_c2f(comm);
112 int rank_proc; MPI_Comm_rank(comm, &rank_proc);
119 if (var.GetComputationalMode() == var.REGULAR_MODE)
121 if (var.GetTypeSpectrum() == var.CENTERED_EIGENVALUES)
123 cout <<
"You can not use regular mode to find "
124 <<
"eigenvalues closest to a given value" << endl;
125 cout <<
"Try to use shifted mode for example "<<endl;
131 if ((var.GetTypeSpectrum() != var.CENTERED_EIGENVALUES) &&
132 (var.GetComputationalMode() != var.INVERT_MODE))
134 cout <<
"To find large or small eigenvalues, use a regular mode" << endl;
138 if (var.GetComputationalMode() == var.IMAG_SHIFTED_MODE)
140 cout <<
"Currently not working" << endl;
144 if ( (var.GetComputationalMode() == var.BUCKLING_MODE)
145 || (var.GetComputationalMode() == var.CAYLEY_MODE) )
149 cout <<
"Cayley or Bucking mode are reserved for real symmetric "
150 <<
"generalized eigenproblems " << endl;
158 if (var.DiagonalMass() || var.UseCholeskyFactoForMass())
160 cout <<
"Complex shifts for unsymmetric real problems are "
161 <<
"not relevant for diagonal or Cholesky-factorized"
163 cout <<
"Specify a general mass matrix" << endl;
164 cout <<
"Diagonal = " << var.DiagonalMass() <<
165 ", Cholesky : " << var.UseCholeskyFactoForMass() << endl;
187 if (var.DiagonalMass() || var.UseCholeskyFactoForMass())
190 if (print_level >= 2)
191 #ifdef SELDON_WITH_MPI
194 cout <<
"We solve a standard eigenvalue problem " << endl;
202 if (var.DiagonalMass())
205 var.ComputeDiagonalMass();
208 var.FactorizeDiagonalMass();
213 var.ComputeMassForCholesky();
216 var.FactorizeCholeskyMass();
219 if (var.GetComputationalMode() == var.REGULAR_MODE)
226 var.ComputeStiffnessMatrix();
229 v.Reallocate(n, ncv);
230 workd.Reallocate(3*n);
231 workl.Reallocate(lworkl);
234 rwork.Reallocate(ncv);
244 if (print_level >= 2)
245 #ifdef SELDON_WITH_MPI
248 cout <<
"Starting Arpack iterations..." << endl;
250 bool test_loop =
true;
253 CallArpack(comm_f, ido, bmat, n, which, nev, tol, resid, ncv, v, ldv,
254 iparam, ipntr, sym, workd, workl, lworkl, rwork, info);
256 if ((ido == -1)||(ido == 1))
260 for (
int i = 0; i < n; i++)
261 Xh(i) = workd(ipntr(0)+i-1);
263 if (var.DiagonalMass())
264 var.MltInvSqrtDiagonalMass(Xh);
266 var.SolveCholeskyMass(SeldonTrans, Xh);
268 var.MltStiffness(Xh, Yh);
269 var.IncrementProdMatVect();
271 if (var.DiagonalMass())
272 var.MltInvSqrtDiagonalMass(Yh);
275 var.SolveCholeskyMass(SeldonNoTrans, Yh);
276 var.IncrementLinearSolves();
279 for (
int i = 0; i < n; i++)
280 workd(ipntr(1)+i-1) = Yh(i);
296 var.ComputeAndFactorizeStiffnessMatrix(-shiftr, one);
299 v.Reallocate(n, ncv);
300 workd.Reallocate(3*n);
301 workl.Reallocate(lworkl);
304 rwork.Reallocate(ncv);
314 if (print_level >= 2)
315 #ifdef SELDON_WITH_MPI
318 cout <<
"Starting Arpack iterations..." << endl;
320 bool test_loop =
true;
323 CallArpack(comm_f, ido, bmat, n, which, nev, tol, resid, ncv, v, ldv,
324 iparam, ipntr, sym, workd, workl, lworkl, rwork, info);
326 if ((ido == -1)||(ido == 1))
330 for (
int i = 0; i < n; i++)
331 Xh(i) = workd(ipntr(0)+i-1);
333 if (var.DiagonalMass())
334 var.MltSqrtDiagonalMass(Xh);
336 var.MltCholeskyMass(SeldonNoTrans, Xh);
338 var.ComputeSolution(Xh, Yh);
339 var.IncrementLinearSolves();
341 if (var.DiagonalMass())
342 var.MltSqrtDiagonalMass(Yh);
345 var.MltCholeskyMass(SeldonTrans, Yh);
346 var.IncrementLinearSolves();
349 for (
int i = 0; i < n; i++)
350 workd(ipntr(1)+i-1) = Yh(i);
363 if (var.GetComputationalMode() == var.INVERT_MODE)
370 if (var.GetTypeSpectrum() != var.CENTERED_EIGENVALUES)
376 var.ComputeAndFactorizeStiffnessMatrix(one, zero);
379 var.ComputeStiffnessMatrix();
389 #ifdef SELDON_WITH_VIRTUAL
390 var.ComputeAndFactorizeStiffnessMatrix(-shift_complex, cone,
393 var.ComputeAndFactorizeStiffnessMatrix(-complex<T>(shiftr, shifti),
394 complex<T>(one, zero),
true);
397 var.ComputeStiffnessMatrix();
406 var.ComputeAndFactorizeStiffnessMatrix(-shiftr, one);
411 var.ComputeMassMatrix();
415 v.Reallocate(n, ncv);
416 workd.Reallocate(3*n);
417 workl.Reallocate(lworkl);
421 rwork.Reallocate(ncv);
432 if (print_level >= 2)
433 #ifdef SELDON_WITH_MPI
436 cout <<
"Starting Arpack iterations..." << endl;
438 bool test_loop =
true;
442 CallArpack(comm_f, ido, bmat, n, which, nev, tol, resid, ncv, v, ldv,
443 iparam, ipntr, non_sym, workd, workl, lworkl, rwork, info);
445 if ((ido == -1)||(ido == 1))
448 if ((iparam(6) == 3) && (ido == 1))
449 for (
int i = 0; i < n; i++)
450 Xh(i) = workd(ipntr(2)+i-1);
452 for (
int i = 0; i < n; i++)
453 Xh(i) = workd(ipntr(0)+i-1);
455 if (var.GetTypeSpectrum() != var.CENTERED_EIGENVALUES)
457 var.MltStiffness(Xh, Zh);
458 var.ComputeSolution(Zh, Yh);
459 var.IncrementProdMatVect();
460 var.IncrementLinearSolves();
465 var.ComputeSolution(Zh, Yh);
466 var.IncrementProdMatVect();
467 var.IncrementLinearSolves();
470 for (
int i = 0; i < n; i++)
471 workd(ipntr(1)+i-1) = Yh(i);
476 for (
int i = 0; i < n; i++)
477 workd(ipntr(1)+i-1) = workd(ipntr(0)+i-1);
483 else if (var.GetComputationalMode() == var.REGULAR_MODE)
490 var.ComputeAndFactorizeStiffnessMatrix(one, zero);
493 var.ComputeStiffnessMatrix();
494 var.ComputeMassMatrix();
497 v.Reallocate(n, ncv);
498 workd.Reallocate(3*n);
499 workl.Reallocate(lworkl);
503 rwork.Reallocate(ncv);
514 if (print_level >= 2)
515 #ifdef SELDON_WITH_MPI
518 cout <<
"Starting Arpack iterations..." << endl;
520 bool test_loop =
true;
523 CallArpack(comm_f, ido, bmat, n, which, nev, tol, resid, ncv, v, ldv,
524 iparam, ipntr, sym, workd, workl, lworkl, rwork, info);
526 if ((ido == -1)||(ido == 1))
529 for (
int i = 0; i < n; i++)
530 Xh(i) = workd(ipntr(0)+i-1);
532 var.MltStiffness(Xh, Zh);
533 var.ComputeSolution(Zh, Yh);
534 var.IncrementProdMatVect();
535 var.IncrementLinearSolves();
537 for (
int i = 0; i < n; i++)
539 workd(ipntr(0)+i-1) = Zh(i);
540 workd(ipntr(1)+i-1) = Yh(i);
546 for (
int i = 0; i < n; i++)
547 Xh(i) = workd(ipntr(0)+i-1);
550 var.IncrementProdMatVect();
552 for (
int i = 0; i < n; i++)
553 workd(ipntr(1)+i-1) = Yh(i);
560 else if ((var.GetComputationalMode() == var.SHIFTED_MODE)
561 || (var.GetComputationalMode() == var.IMAG_SHIFTED_MODE) )
569 #ifdef SELDON_WITH_VIRTUAL
570 if (var.GetComputationalMode() == var.SHIFTED_MODE)
571 var.ComputeAndFactorizeStiffnessMatrix(-shift_complex, cone,
576 var.ComputeAndFactorizeStiffnessMatrix(-shift_complex, cone,
580 if (var.GetComputationalMode() == var.SHIFTED_MODE)
581 var.ComputeAndFactorizeStiffnessMatrix(-complex<T>(shiftr, shifti),
582 complex<T>(one, zero),
true);
586 var.ComputeAndFactorizeStiffnessMatrix(-complex<T>(shiftr, shifti),
587 complex<T>(one, zero),
false);
591 var.ComputeStiffnessMatrix();
594 var.ComputeAndFactorizeStiffnessMatrix(-shiftr, one);
597 var.ComputeMassMatrix();
600 v.Reallocate(n, ncv);
601 workd.Reallocate(3*n);
602 workl.Reallocate(lworkl);
606 rwork.Reallocate(ncv);
617 if (print_level >= 2)
618 #ifdef SELDON_WITH_MPI
621 cout <<
"Starting Arpack iterations..." << endl;
623 bool test_loop =
true;
626 CallArpack(comm_f, ido, bmat, n, which, nev, tol, resid, ncv, v, ldv,
627 iparam, ipntr, sym, workd, workl, lworkl, rwork, info);
629 if ((ido == -1)||(ido == 1))
636 for (
int i = 0; i < n; i++)
637 Zh(i) = workd(ipntr(0)+i-1);
640 var.IncrementProdMatVect();
643 for (
int i = 0; i < n; i++)
644 Xh(i) = workd(ipntr(2)+i-1);
646 var.ComputeSolution(Xh, Yh);
647 var.IncrementLinearSolves();
648 for (
int i = 0; i < n; i++)
649 workd(ipntr(1)+i-1) = Yh(i);
655 for (
int i = 0; i < n; i++)
656 Xh(i) = workd(ipntr(0)+i-1);
659 var.IncrementProdMatVect();
661 for (
int i = 0; i < n; i++)
662 workd(ipntr(1)+i-1) = Yh(i);
670 else if (var.GetComputationalMode() == var.BUCKLING_MODE)
676 var.ComputeAndFactorizeStiffnessMatrix(-shiftr, one);
679 var.ComputeStiffnessMatrix();
682 v.Reallocate(n, ncv);
683 workd.Reallocate(3*n);
684 workl.Reallocate(lworkl);
688 rwork.Reallocate(ncv);
699 if (print_level >= 2)
700 #ifdef SELDON_WITH_MPI
703 cout <<
"Starting Arpack iterations..." << endl;
705 bool test_loop =
true;
708 CallArpack(comm_f, ido, bmat, n, which, nev, tol, resid, ncv, v, ldv,
709 iparam, ipntr, sym, workd, workl, lworkl, rwork, info);
711 if ((ido == -1)||(ido == 1))
716 for (
int i = 0; i < n; i++)
717 Zh(i) = workd(ipntr(0)+i-1);
719 var.MltStiffness(Zh, Xh);
720 var.IncrementProdMatVect();
723 for (
int i = 0; i < n; i++)
724 Xh(i) = workd(ipntr(2)+i-1);
726 var.ComputeSolution(Xh, Yh);
727 var.IncrementLinearSolves();
729 for (
int i = 0; i < n; i++)
730 workd(ipntr(1)+i-1) = Yh(i);
735 for (
int i = 0; i < n; i++)
736 Xh(i) = workd(ipntr(0)+i-1);
738 var.MltStiffness(Xh, Yh);
739 var.IncrementProdMatVect();
741 for (
int i = 0; i < n; i++)
742 workd(ipntr(1)+i-1) = Yh(i);
749 else if (var.GetComputationalMode() == var.CAYLEY_MODE)
755 var.ComputeAndFactorizeStiffnessMatrix(-shiftr, one);
758 var.ComputeMassMatrix();
759 var.ComputeStiffnessMatrix(shiftr, one);
762 v.Reallocate(n, ncv);
763 workd.Reallocate(3*n);
764 workl.Reallocate(lworkl);
768 rwork.Reallocate(ncv);
779 if (print_level >= 2)
780 #ifdef SELDON_WITH_MPI
783 cout <<
"Starting Arpack iterations..." << endl;
785 bool test_loop =
true;
788 CallArpack(comm_f, ido, bmat, n, which, nev, tol, resid, ncv, v, ldv,
789 iparam, ipntr, sym, workd, workl, lworkl, rwork, info);
791 if ((ido == -1)||(ido == 1))
794 for (
int i = 0; i < n; i++)
795 Zh(i) = workd(ipntr(0)+i-1);
797 var.MltStiffness(shiftr, one, Zh, Xh);
798 var.ComputeSolution(Xh, Yh);
799 var.IncrementProdMatVect();
800 var.IncrementLinearSolves();
802 for (
int i = 0; i < n; i++)
803 workd(ipntr(1)+i-1) = Yh(i);
808 for (
int i = 0; i < n; i++)
809 Xh(i) = workd(ipntr(0)+i-1);
812 var.IncrementProdMatVect();
814 for (
int i = 0; i < n; i++)
815 workd(ipntr(1)+i-1) = Yh(i);
828 cout <<
"Maximum number of iterations reached" << endl;
829 cout <<
"Try again with a larger number of iterations"
830 <<
" or with a less restrictive stopping criterion" << endl;
836 cout <<
"Error during the computation of eigenvalues, info = "
838 cout <<
"Look at documentation of ARPACK " << endl;
848 if ((
Norm2(resid) == 0) && (n > ncv))
850 cout <<
"This eigenvalue problem rises an unknown bug in Arpack " << endl;
851 cout <<
"Is the mass matrix or stiffness matrix null ?" << endl;
852 cout <<
"Null eigenvalues are found." << endl;
857 int nconv = nev+1+var.GetNbAdditionalEigenvalues();
858 eigen_values.Reallocate(nconv);
859 eigen_vectors.Reallocate(n, nconv);
860 eigen_values.Fill(zero);
861 eigen_vectors.Fill(zero);
862 lambda_imag.Reallocate(nconv);
863 lambda_imag.Fill(zero);
866 IVect selec(ncv); selec.Zero();
869 if (print_level >= 2)
870 #ifdef SELDON_WITH_MPI
873 cout <<
"recovering eigenvalues ..." << endl;
875 CallArpack(comm_f, rvec, howmny, selec, eigen_values, lambda_imag, eigen_vectors,
876 ldz, shiftr, shifti, bmat, n, which, nev, tol, resid, ncv,
877 v, ldv, iparam, ipntr, sym_mode, workd, workl, lworkl, rwork, info);
879 if (print_level >= 2)
880 #ifdef SELDON_WITH_MPI
883 cout <<
"end recover " << endl;
885 eigen_values.Resize(nev);
886 lambda_imag.Resize(nev);
887 eigen_vectors.Resize(n, nev);
901 template<
class T,
class Allocator1,
class Allocator2,
902 class Allocator3,
class Allocator4,
class Alloc5>
903 void CallArpack(
int comm,
int& ido,
char& bmat,
int& n,
string& which,
int& nev,
913 if ((which ==
"SR") || (which ==
"SI"))
916 if ((which ==
"LR") || (which ==
"LI"))
921 #ifdef SELDON_WITH_MPI
922 saupd(comm, ido, bmat, n, &which[0], nev, tol, resid.GetData(),
923 ncv, v.GetData(), ldv, iparam.GetData(), ipntr.GetData(),
924 workd.GetData(), workl.GetData(), lworkl, info);
926 saupd(ido, bmat, n, &which[0], nev, tol, resid.GetData(),
927 ncv, v.GetData(), ldv, iparam.GetData(), ipntr.GetData(),
928 workd.GetData(), workl.GetData(), lworkl, info);
935 #ifdef SELDON_WITH_MPI
936 naupd(comm, ido, bmat, n, &which[0], nev, tol, resid.GetData(),
937 ncv, v.GetData(), ldv, iparam.GetData(), ipntr.GetData(),
938 workd.GetData(), workl.GetData(), lworkl, info);
940 naupd(ido, bmat, n, &which[0], nev, tol, resid.GetData(),
941 ncv, v.GetData(), ldv, iparam.GetData(), ipntr.GetData(),
942 workd.GetData(), workl.GetData(), lworkl, info);
949 template<
class Allocator1,
class Allocator2,
950 class Allocator3,
class Allocator4,
class Alloc5>
952 string& which,
int& nev,
double& tol,
962 #ifdef SELDON_WITH_MPI
963 pznaupd_(&comm, &ido, &bmat, &n, &which[0], &nev, &tol, resid.GetDataVoid(),
964 &ncv, v.GetDataVoid(), &ldv, iparam.GetData(), ipntr.GetData(),
965 workd.GetDataVoid(), workl.GetDataVoid(), &lworkl, rwork.GetData(), &info);
967 znaupd_(&ido, &bmat, &n, &which[0], &nev, &tol, resid.GetDataVoid(),
968 &ncv, v.GetDataVoid(), &ldv, iparam.GetData(), ipntr.GetData(),
969 workd.GetDataVoid(), workl.GetDataVoid(), &lworkl, rwork.GetData(), &info);
975 template<
class T,
class Allocator1,
class Allocator2,
976 class Allocator3,
class Allocator4,
class Allocator5,
977 class Allocator6,
class Allocator7,
class Alloc8>
982 int& ldz, T& shiftr, T& shifti,
char& bmat,
int& n,
983 string& which,
int& nev, T& tol,
995 #ifdef SELDON_WITH_MPI
996 seupd(comm, rvec, howmny, selec.GetData(), lambda.GetData(), eigen_vec.GetData(),
997 ldz, shiftr, bmat, n, &which[0], nev, tol, resid.GetData(), ncv,
998 v.GetData(), ldv, iparam.GetData(), ipntr.GetData(),
999 workd.GetData(), workl.GetData(), lworkl, info);
1001 seupd(rvec, howmny, selec.GetData(), lambda.GetData(), eigen_vec.GetData(),
1002 ldz, shiftr, bmat, n, &which[0], nev, tol, resid.GetData(), ncv,
1003 v.GetData(), ldv, iparam.GetData(), ipntr.GetData(),
1004 workd.GetData(), workl.GetData(), lworkl, info);
1012 #ifdef SELDON_WITH_MPI
1013 neupd(comm, rvec, howmny, selec.GetData(), lambda.GetData(),
1014 lambda_i.GetData(), eigen_vec.GetData(), ldz, shiftr, shifti,
1015 workev.GetData(), bmat, n, &which[0], nev, tol,
1016 resid.GetData(), ncv, v.GetData(), ldv, iparam.GetData(),
1017 ipntr.GetData(), workd.GetData(), workl.GetData(), lworkl, info);
1019 neupd(rvec, howmny, selec.GetData(), lambda.GetData(),
1020 lambda_i.GetData(), eigen_vec.GetData(), ldz, shiftr, shifti,
1021 workev.GetData(), bmat, n, &which[0], nev, tol,
1022 resid.GetData(), ncv, v.GetData(), ldv, iparam.GetData(),
1023 ipntr.GetData(), workd.GetData(), workl.GetData(), lworkl, info);
1030 template<
class Allocator1,
class Allocator2,
class Allocator3,
1031 class Allocator4,
class Allocator5,
class Allocator6,
1032 class Allocator7,
class Alloc8>
1037 int& ldz, complex<double>& shiftr, complex<double>& shifti,
1038 char& bmat,
int& n,
string& which,
int& nev,
double& tol,
1050 #ifdef SELDON_WITH_MPI
1051 pzneupd_(&comm, &rvec, &howmny, selec.GetData(), lambda.GetDataVoid(),
1052 eigen_vectors.GetDataVoid(), &ldz, &shiftr, workev.GetDataVoid(),
1053 &bmat, &n, &which[0], &nev, &tol, resid.GetDataVoid(),
1054 &ncv, v.GetDataVoid(), &ldv, iparam.GetData(),
1055 ipntr.GetData(), workd.GetDataVoid(), workl.GetDataVoid(),
1056 &lworkl, rwork.GetData(), &info);
1058 zneupd_(&rvec, &howmny, selec.GetData(), lambda.GetDataVoid(),
1059 eigen_vectors.GetDataVoid(), &ldz, &shiftr, workev.GetDataVoid(),
1060 &bmat, &n, &which[0], &nev, &tol, resid.GetDataVoid(),
1061 &ncv, v.GetDataVoid(), &ldv, iparam.GetData(),
1062 ipntr.GetData(), workd.GetDataVoid(), workl.GetDataVoid(),
1063 &lworkl, rwork.GetData(), &info);
1069 #define SELDON_FILE_ARPACK_CXX