1 #ifndef SELDON_FILE_POLYNOMIAL_EIGENVALUE_SOLVER_CXX
3 #include "PolynomialEigenvalueSolver.hxx"
7 SlepcParamPep::SlepcParamPep()
12 int SlepcParamPep::GetEigensolverType()
const
17 void SlepcParamPep::SetEigensolverType(
int type)
31 use_spectral_transfo =
false;
33 diagonal_mass =
false;
41 return use_spectral_transfo;
49 use_spectral_transfo = t;
97 cout <<
"ComputeOperator not overloaded" << endl;
106 cout <<
"MltOperator not overloaded" << endl;
115 cout <<
"FactorizeMass not overloaded" << endl;
126 for (
int i = 0; i < x.GetM(); i++)
127 y(i) = x(i)*this->invDiag(i);
130 cout <<
"SolveMass not overloaded" << endl;
139 cout <<
"FactorizeOperator not overloaded" << endl;
145 void PolynomialEigenProblem_Base<T>
146 ::SolveOperator(
const SeldonTranspose&,
const Vector<T>& X, Vector<T>& Y)
148 cout <<
"SolveOperator not overloaded" << endl;
163 this->Init(op(0)->GetM());
168 this->pol_degree = list_op.GetM()-1;
176 if (num >= list_coef.GetM())
177 list_coef.Resize(num+1);
179 list_coef(num) = coef;
186 if (list_op.GetM() <= 0)
189 if (list_coef.GetM() == 0)
192 list_op(num)->MltVector(trans, X, Y);
197 T zero; SetComplexZero(zero);
198 T one; SetComplexOne(one);
199 if (list_coef(num)(0) != zero)
201 list_op(0)->MltVector(trans, X, Y);
202 Mlt(list_coef(num)(0), Y);
207 for (
int i = 1; i < list_op.GetM(); i++)
208 if (list_coef(num)(i) != zero)
209 list_op(i)->MltAddVector(list_coef(num)(i), trans, X, one, Y);
217 for (
int i = 0; i < this->list_op.GetM(); i++)
218 if (!this->list_op(i)->IsSymmetric())
238 template<
class T,
class Prop,
class Storage>
242 for (
int i = 0; i < op0.GetM(); i++)
249 template<
class T,
class Prop,
class Storage>
252 if (this->DiagonalMass())
254 T one; SetComplexOne(one);
255 this->invDiag.Reallocate(this->n_);
257 for (
int i = 0; i < this->n_; i++)
258 this->invDiag(i) = one / M(i, i);
262 mat_lu = *list_mat(this->pol_degree);
263 GetLU(mat_lu, pivot);
267 template<
class T,
class Prop,
class Storage>
271 if (this->DiagonalMass())
272 for (
int i = 0; i < x.GetM(); i++)
273 y(i) = x(i)*this->invDiag(i);
276 if (!trans.NoTrans())
278 cout <<
"Not implemented" << endl;
283 SolveLU(mat_lu, pivot, y);
287 template<
class T,
class Prop,
class Storage>
290 T zero; SetComplexZero(zero);
293 mat_lu.Reallocate(this->n_, this->n_);
298 mat_lu = *list_mat(0);
299 Mlt(coef(0), mat_lu);
302 for (
int k = 1; k < list_mat.GetM(); k++)
304 Add(coef(k), *list_mat(k), mat_lu);
306 GetLU(mat_lu, pivot);
309 template<
class T,
class Prop,
class Storage>
310 void PolynomialDenseEigenProblem<T, Prop, Storage>
311 ::SolveOperator(
const SeldonTranspose& trans,
const Vector<T>& X, Vector<T>& Y)
313 if (!trans.NoTrans())
315 cout <<
"Not implemented" << endl;
320 SolveLU(mat_lu, pivot, Y);
328 template<
class T,
class MatStiff,
class MatMass>
329 PolynomialSparseEigenProblem<T, MatStiff, MatMass>::PolynomialSparseEigenProblem()
332 ProcSharingRows = NULL;
333 SharingRowNumbers = NULL;
334 nodl_scalar_ = nb_unknowns_scal_ = 0;
338 template<
class T,
class MatStiff,
class MatMass>
339 int PolynomialSparseEigenProblem<T, MatStiff, MatMass>::RetrieveLocalNumbers(MatStiff& K)
343 #ifdef SELDON_WITH_MPI
346 DistributedMatrix_Base<typename MatStiff::entry_type>& A
347 =
dynamic_cast<DistributedMatrix_Base<typename MatStiff::entry_type>&
>(K);
349 MPI_Comm comm = A.GetCommunicator();
350 this->SetCommunicator(comm);
352 MPI_Comm_size(comm, &nb_proc);
359 int m = A.GetLocalM();
360 const IVect& OverlapRow = A.GetOverlapRowNumber();
361 int noverlap = OverlapRow.GetM();
362 int n = m - noverlap;
363 local_col_numbers.Reallocate(n);
364 Vector<bool> OverlappedRow(m); OverlappedRow.Fill(
false);
365 for (
int i = 0; i < noverlap; i++)
366 OverlappedRow(OverlapRow(i)) =
true;
369 for (
int i = 0; i < m; i++)
370 if (!OverlappedRow(i))
371 local_col_numbers(ncol++) = i;
373 ProcSharingRows = &A.GetProcessorSharingRows();
374 SharingRowNumbers = &A.GetSharingRowNumbers();
375 nodl_scalar_ = A.GetNodlScalar();
376 nb_unknowns_scal_ = A.GetNbScalarUnknowns();
380 catch (
const std::bad_cast&)
383 this->SetCommunicator(MPI_COMM_SELF);
385 local_col_numbers.Clear();
392 template<
class T,
class MatStiff,
class MatMass>
393 void PolynomialSparseEigenProblem<T, MatStiff, MatMass>::InitMatrix(Vector<MatStiff*>& K, MatMass& M)
395 int n = RetrieveLocalNumbers(*K(0));
400 Vector<VirtualMatrix<T>* > list_op(K.GetM() + 1);
401 for (
int i = 0; i < K.GetM(); i++)
404 list_op(K.GetM()) = &M;
407 Kh.Reallocate(K.GetM());
408 for (
int i = 0; i < K.GetM(); i++)
414 template<
class T,
class MatStiff,
class MatMass>
417 if (this->DiagonalMass())
419 T one; SetComplexOne(one);
420 this->invDiag.Reallocate(nloc);
421 for (
int i = 0; i < nloc; i++)
422 this->invDiag(i) = (*Mh)(i, i);
427 #ifdef SELDON_WITH_MPI
429 AssembleVector(M, MPI_SUM, *ProcSharingRows, *SharingRowNumbers,
430 this->comm, nodl_scalar_, nb_unknowns_scal_, 15);
432 this->invDiag.Reallocate(local_col_numbers.GetM());
433 for (
int i = 0; i < local_col_numbers.GetM(); i++)
434 this->invDiag(i) = one / M(local_col_numbers(i));
438 for (
int i = 0; i < nloc; i++)
439 this->invDiag(i) = one / this->invDiag(i);
443 mat_lu.Factorize(*Mh);
447 template<
class T,
class MatStiff,
class MatMass>
451 if (this->DiagonalMass())
452 for (
int i = 0; i < x.GetM(); i++)
453 y(i) = x(i)*this->invDiag(i);
455 this->SolveOperator(trans, x, y);
459 template<
class T,
class MatStiff,
class MatMass>
463 T zero; SetComplexZero(zero);
466 for (
int k = 1; k < Kh.GetM(); k++)
468 Add(coef(k), *Kh(k), A);
470 Add(coef(Kh.GetM()), *Mh, A);
475 template<
class T,
class MatStiff,
class MatMass>
476 void PolynomialSparseEigenProblem<T, MatStiff, MatMass>
477 ::SolveOperator(
const SeldonTranspose& trans,
const Vector<T>& x, Vector<T>& y)
483 for (
int i = 0; i < this->n_; i++)
484 X(local_col_numbers(i)) = x(i);
489 mat_lu.Solve(trans, X,
false);
492 for (
int i = 0; i < this->n_; i++)
493 y(i) = X(local_col_numbers(i));
500 template<
class T,
class MatStiff,
class MatMass>
509 #ifdef SELDON_WITH_MPI
510 X.Reallocate(nloc); Y.Reallocate(nloc);
512 for (
int i = 0; i < this->n_; i++)
513 X(local_col_numbers(i)) = x(i);
515 AssembleVector(X, MPI_SUM, *ProcSharingRows, *SharingRowNumbers,
516 this->comm, nodl_scalar_, nb_unknowns_scal_, 17);
518 if (this->list_coef.GetM() == 0)
519 this->list_op(num)->MltVector(trans, X, Y);
523 T zero; SetComplexZero(zero);
524 T one; SetComplexOne(one);
525 if (this->list_coef(num)(0) != zero)
527 this->list_op(0)->MltVector(trans, X, Y);
528 Mlt(this->list_coef(num)(0), Y);
533 for (
int i = 1; i < this->list_op.GetM(); i++)
534 if (this->list_coef(num)(i) != zero)
535 this->list_op(i)->MltAddVector(this->list_coef(num)(i), trans, X, one, Y);
538 for (
int i = 0; i < this->n_; i++)
539 y(i) = Y(local_col_numbers(i));
548 template<
class T,
class MatStiff,
class MatMass>
553 #ifdef SELDON_WITH_MPI
554 this->AssembleEigenvectors(eigen_vec, local_col_numbers, ProcSharingRows,
555 SharingRowNumbers, nloc, nodl_scalar_, nb_unknowns_scal_);
561 template<
class T,
class Prop,
class Storage>
567 if (type_solver == TypeEigenvalueSolver::DEFAULT)
570 if (type_solver == TypeEigenvalueSolver::FEAST)
572 #ifdef SELDON_WITH_FEAST
573 T zero; SetComplexZero(zero);
575 FindEigenvaluesFeast(var_eig, lambda, lambda_imag, eigen_old);
579 eigen_vec, var_eig.LARGE_EIGENVALUES,
582 cout <<
"Recompile with MKL or Feast" << endl;
586 else if (type_solver == TypeEigenvalueSolver::SLEPC)
588 #ifdef SELDON_WITH_SLEPC
589 T zero; SetComplexZero(zero);
590 Matrix<T, General, ColMajor> eigen_old;
591 FindEigenvaluesSlepc(var_eig, lambda, lambda_imag, eigen_old);
595 eigen_vec, var_eig.LARGE_EIGENVALUES,
598 cout <<
"Recompile with Slepc" << endl;
604 cout <<
"Recompile with eigenvalue solver" << endl;
612 #define SELDON_FILE_POLYNOMIAL_EIGENVALUE_SOLVER_CXX