1 #ifndef SELDON_FILE_NON_LINEAR_EIGENVALUE_SOLVER_CXX
3 #include "NonLinearEigenvalueSolver.hxx"
8 #ifdef SELDON_WITH_SLEPC
10 SlepcParamNep::SlepcParamNep()
13 use_command_line_options =
false;
14 a_sp = 0.1; b_sp = 10.0; c_sp = 0.1; d_sp = 10.0;
16 locking_variant =
true;
20 use_default_petsc_solver =
false;
23 int SlepcParamNep::GetEigensolverType()
const
28 void SlepcParamNep::SetEigensolverType(
int type)
33 double SlepcParamNep::GetLrMin()
const
38 double SlepcParamNep::GetLrMax()
const
43 double SlepcParamNep::GetLiMin()
const
48 double SlepcParamNep::GetLiMax()
const
53 void SlepcParamNep::SetIntervalRegion(
double a,
double b,
double c,
double d)
55 a_sp = a; b_sp = b; c_sp = c; d_sp = d;
58 bool SlepcParamNep::InsideRegion(
const complex<double>& z)
const
60 if ((real(z) >= a_sp) && (real(z) <= b_sp)
61 && (imag(z) >= c_sp) && (imag(z) <= d_sp))
67 void SlepcParamNep::EnableCommandLineOptions(
bool yes)
69 use_command_line_options = yes;
72 bool SlepcParamNep::UseCommandLineOptions()
const
74 return use_command_line_options;
77 void SlepcParamNep::SetDefaultPetscSolver(
bool yes)
79 use_default_petsc_solver = yes;
82 bool SlepcParamNep::UseDefaultPetscSolver()
const
84 return use_default_petsc_solver;
87 void SlepcParamNep::SetFullBasis(
bool yes)
92 bool SlepcParamNep::FullBasis()
const
97 void SlepcParamNep::SetLockingVariant(
bool yes)
99 locking_variant = yes;
102 bool SlepcParamNep::LockingVariant()
const
104 return locking_variant;
107 void SlepcParamNep::SetInterpolationDegree(
int p)
112 int SlepcParamNep::GetInterpolationDegree()
const
114 return degree_interpol;
117 void SlepcParamNep::SetInterpolationTolerance(
double eps)
122 double SlepcParamNep::GetInterpolationTolerance()
const
127 void SlepcParamNep::SetRestartNleigs(
double r)
132 double SlepcParamNep::GetRestartNleigs()
const
137 void SlepcParamNep::SetRKShifts(
const Vector<Petsc_Scalar>& s)
142 const Vector<Petsc_Scalar>& SlepcParamNep::GetRKShifts()
const
155 NonLinearEigenProblem_Base<T>::NonLinearEigenProblem_Base()
157 exact_preconditioning =
false;
158 explicit_matrix =
false;
160 this->automatic_selection_arnoldi_vectors =
false;
161 this->nb_arnoldi_vectors = 0;
167 SlepcParamNep& NonLinearEigenProblem_Base<T>::GetSlepcParameters()
175 void NonLinearEigenProblem_Base<T>::SetExactPreconditioning(
bool yes)
177 exact_preconditioning = yes;
183 bool NonLinearEigenProblem_Base<T>::ExactPreconditioning()
const
185 return exact_preconditioning;
191 const Vector<T>& NonLinearEigenProblem_Base<T>::GetSingularities()
const
193 return singular_points;
199 void NonLinearEigenProblem_Base<T>::SetSingularities(
const Vector<T>& s)
207 void NonLinearEigenProblem_Base<T>::SetExplicitMatrix(
bool yes)
209 explicit_matrix = yes;
215 bool NonLinearEigenProblem_Base<T>::ExplicitMatrix()
const
217 return explicit_matrix;
223 void NonLinearEigenProblem_Base<T>::SetSplitMatrices(
int n)
226 numer_pol_split.Reallocate(n);
227 denom_pol_split.Reallocate(n);
233 bool NonLinearEigenProblem_Base<T>::UseSplitMatrices()
const
235 if (nb_split_matrix > 1)
244 int NonLinearEigenProblem_Base<T>::GetNbSplitMatrices()
const
246 return nb_split_matrix;
252 void NonLinearEigenProblem_Base<T>::SetNumeratorSplitFct(
int i,
const Vector<T>& coef)
254 numer_pol_split(i) = coef;
260 void NonLinearEigenProblem_Base<T>::SetDenominatorSplitFct(
int i,
const Vector<T>& coef)
262 denom_pol_split(i) = coef;
268 const Vector<T>& NonLinearEigenProblem_Base<T>::GetNumeratorSplitFct(
int i)
270 return numer_pol_split(i);
276 const Vector<T>& NonLinearEigenProblem_Base<T>::GetDenominatorSplitFct(
int i)
278 return denom_pol_split(i);
284 void NonLinearEigenProblem_Base<T>::CheckValueL(
const T& L)
286 if (isinf(abs(L)) || isnan(abs(L)))
288 cout <<
"Invalid value for L : " << L << endl;
296 void NonLinearEigenProblem_Base<T>::ComputeOperator(
const T& L)
298 cout <<
"ComputeOperator not overloaded" << endl;
305 void NonLinearEigenProblem_Base<T>::MltOperator(
const T& L,
const SeldonTranspose&,
const Vector<T>& X, Vector<T>& Y)
307 cout <<
"MltOperator not overloaded" << endl;
314 void NonLinearEigenProblem_Base<T>::ComputeOperatorExplicit(
const T& L, DistributedMatrix<T, General, ArrayRowSparse>& A)
316 cout <<
"ComputeOperatorExplicit not overloaded" << endl;
323 void NonLinearEigenProblem_Base<T>::ComputeJacobian(
const T& L)
325 cout <<
"ComputeJacobian not overloaded" << endl;
331 void NonLinearEigenProblem_Base<T>::MltJacobian(
const T& L,
const SeldonTranspose&,
const Vector<T>& X, Vector<T>& Y)
333 cout <<
"MltJacobian not overloaded" << endl;
339 void NonLinearEigenProblem_Base<T>::ComputeJacobianExplicit(
const T& L, DistributedMatrix<T, General, ArrayRowSparse>& A)
341 cout <<
"ComputeOperatorExplicit not overloaded" << endl;
348 void NonLinearEigenProblem_Base<T>::ComputePreconditioning(
const T& L)
350 cout <<
"ComputePreconditioning not overloaded" << endl;
356 void NonLinearEigenProblem_Base<T>::ComputePreconditioning(
const Vector<T>& L,
const Vector<T>& coef)
358 cout <<
"ComputePreconditioning not overloaded" << endl;
366 void NonLinearEigenProblem_Base<T>::ComputeSplitPreconditioning(
const Vector<int>& num,
const Vector<T>& coef)
368 cout <<
"ComputeSplitPreconditioning not overloaded" << endl;
375 void NonLinearEigenProblem_Base<T>::ComputeExplicitPreconditioning(DistributedMatrix<T, General, ArrayRowSparse>& A)
377 cout <<
"ComputeExplicitPreconditioning not overloaded" << endl;
383 void NonLinearEigenProblem_Base<T>::ApplyPreconditioning(
const SeldonTranspose&,
const Vector<T>& X, Vector<T>& Y)
385 cout <<
"ApplyPreconditioning not overloaded" << endl;
391 void NonLinearEigenProblem_Base<T>
392 ::ComputeOperatorSplitExplicit(
int i, DistributedMatrix<T, General, ArrayRowSparse>& A)
394 cout <<
"ComputeOperatorSplitExplicit not overloaded" << endl;
400 void NonLinearEigenProblem_Base<T>
401 ::MltOperatorSplit(
int i,
const SeldonTranspose&,
const Vector<T>& X, Vector<T>& Y)
403 cout <<
"MltOperatorSplit not overloaded" << endl;
413 template<
class T,
class Prop,
class Storage>
414 void SplitSparseNonLinearEigenProblem<T, Prop, Storage>::CheckPresenceMatrix()
const
418 cout <<
"Matrices A_i not initialized" << endl;
419 cout <<
"Did you call InitMatrix ? " << endl;
426 template<
class T,
class Prop,
class Storage>
427 SplitSparseNonLinearEigenProblem<T, Prop, Storage>::SplitSparseNonLinearEigenProblem()
430 vec_Ai = NULL; nloc = 0;
431 this->exact_preconditioning =
true;
436 template<
class T,
class Prop,
class Storage>
437 void SplitSparseNonLinearEigenProblem<T, Prop, Storage>
438 ::InitMatrix(Vector<DistributedMatrix<T, Prop, Storage> >& A,
439 const Vector<Vector<T> >& numer,
const Vector<Vector<T> >& denom)
441 this->SetSplitMatrices(A.GetM());
443 this->numer_pol_split = numer;
444 this->denom_pol_split = denom;
445 this->mat_lu.Clear();
447 this->SetCommunicator(A(0).GetCommunicator());
449 MPI_Comm_size(this->comm, &nb_proc);
453 local_col_numbers.Clear();
454 this->Init(A(0).GetM());
460 for (
int i = 1; i < A.GetM(); i++)
461 if (!A(0).SameDistributedRows(A(i)))
463 cout <<
"Matrices A_i must have the same distributed rows" << endl;
464 cout <<
"Matrix " << i <<
" is different" << endl;
469 int m = A(0).GetLocalM(); nloc = m;
470 const IVect& OverlapRow = A(0).GetOverlapRowNumber();
471 int noverlap = OverlapRow.GetM();
472 int n = m - noverlap;
475 local_col_numbers.Reallocate(n);
476 Vector<bool> OverlappedRow(m); OverlappedRow.Fill(
false);
477 for (
int i = 0; i < noverlap; i++)
478 OverlappedRow(OverlapRow(i)) =
true;
481 for (
int i = 0; i < m; i++)
482 if (!OverlappedRow(i))
483 local_col_numbers(ncol++) = i;
486 ProcSharingRows = &A(0).GetProcessorSharingRows();
487 SharingRowNumbers = &A(0).GetSharingRowNumbers();
488 nodl_scalar_ = A(0).GetNodlScalar();
489 nb_unknowns_scal_ = A(0).GetNbScalarUnknowns();
497 template<
class T,
class Prop,
class Storage>
498 SparseDistributedSolver<T>& SplitSparseNonLinearEigenProblem<T, Prop, Storage>
506 template<
class T,
class Prop,
class Storage>
507 bool SplitSparseNonLinearEigenProblem<T, Prop, Storage>::IsSymmetricProblem()
const
509 CheckPresenceMatrix();
510 for (
int i = 0; i < vec_Ai->GetM(); i++)
511 if (!(*vec_Ai)(i).IsSymmetric())
519 template<
class T,
class Prop,
class Storage>
520 void SplitSparseNonLinearEigenProblem<T, Prop, Storage>
521 ::ComputeSplitPreconditioning(
const Vector<int>& numL,
const Vector<T>& coef)
523 DistributedMatrix<T, Prop, Storage> A;
524 A = (*vec_Ai)(numL(0)); Mlt(coef(0), A);
525 for (
int i = 1; i < numL.GetM(); i++)
526 Add(coef(i), (*vec_Ai)(numL(i)), A);
528 if (this->print_level >= 2)
529 mat_lu.ShowMessages();
532 mat_lu.HideMessages();
537 template<
class T,
class Prop,
class Storage>
538 void SplitSparseNonLinearEigenProblem<T, Prop, Storage>
539 ::ComputeExplicitPreconditioning(DistributedMatrix<T, General, ArrayRowSparse>& A)
543 cout <<
"not implemented" << endl;
547 if (this->print_level >= 2)
548 mat_lu.ShowMessages();
551 mat_lu.HideMessages();
556 template<
class T,
class Prop,
class Storage>
557 void SplitSparseNonLinearEigenProblem<T, Prop, Storage>
558 ::ApplyPreconditioning(
const SeldonTranspose& trans,
const Vector<T>& X, Vector<T>& Y)
562 Vector<T> Xd(nloc); Xd.Zero();
563 for (
int i = 0; i < this->n_; i++)
564 Xd(local_col_numbers(i)) = X(i);
566 mat_lu.Solve(trans, Xd,
false);
568 for (
int i = 0; i < this->n_; i++)
569 Y(i) = Xd(local_col_numbers(i));
574 mat_lu.Solve(trans, Y);
580 template<
class T,
class Prop,
class Storage>
581 void SplitSparseNonLinearEigenProblem<T, Prop, Storage>
582 ::ComputeOperatorSplitExplicit(
int i, DistributedMatrix<T, General, ArrayRowSparse>& A)
586 cout <<
"not implemented" << endl;
590 Copy((*vec_Ai)(i), A);
595 template<
class T,
class Prop,
class Storage>
596 void SplitSparseNonLinearEigenProblem<T, Prop, Storage>
597 ::MltOperatorSplit(
int i,
const SeldonTranspose& trans,
const Vector<T>& X, Vector<T>& Y)
601 Vector<T> Xd(nloc), Yd(nloc); Xd.Zero();
602 for (
int i = 0; i < this->n_; i++)
603 Xd(local_col_numbers(i)) = X(i);
605 AssembleVector(Xd, MPI_SUM, *ProcSharingRows, *SharingRowNumbers,
606 this->comm, nodl_scalar_, nb_unknowns_scal_, 18);
608 Mlt(trans, (*vec_Ai)(i), Xd, Yd);
610 for (
int i = 0; i < this->n_; i++)
611 Y(i) = Yd(local_col_numbers(i));
614 Mlt(trans, (*vec_Ai)(i), X, Y);
619 template<
class T,
class Prop,
class Storage>
620 void SplitSparseNonLinearEigenProblem<T, Prop, Storage>::DistributeEigenvectors(Matrix<T, General, ColMajor>& eigen_vec)
624 this->AssembleEigenvectors(eigen_vec, local_col_numbers, ProcSharingRows,
625 SharingRowNumbers, nloc, nodl_scalar_, nb_unknowns_scal_);
629 template<
class T,
class Prop,
class Storage>
630 void GetEigenvaluesEigenvectors(NonLinearEigenProblem_Base<T>& var_eig,
631 Vector<T>& lambda, Vector<T>& lambda_imag,
632 Matrix<T, Prop, Storage>& eigen_vec,
635 if (type_solver == TypeEigenvalueSolver::DEFAULT)
638 if (type_solver == TypeEigenvalueSolver::SLEPC)
640 #ifdef SELDON_WITH_SLEPC
641 T zero; SetComplexZero(zero);
642 Matrix<T, General, ColMajor> eigen_old;
643 FindEigenvaluesSlepc(var_eig, lambda, lambda_imag, eigen_old);
647 eigen_vec, var_eig.LARGE_EIGENVALUES,
648 var_eig.GetTypeSorting(), zero, zero);
650 cout <<
"Recompile with Slepc" << endl;
656 cout <<
"Recompile with eigenvalue solver" << endl;
667 #define SELDON_FILE_POLYNOMIAL_EIGENVALUE_SOLVER_CXX