22#ifndef EXADG_SOLVERS_AND_PRECONDITIONERS_UTILITIES_COMPUTE_EIGENVALUES_H_
23#define EXADG_SOLVERS_AND_PRECONDITIONERS_UTILITIES_COMPUTE_EIGENVALUES_H_
26#include <deal.II/numerics/vector_tools_mean_value.h>
29#include <exadg/solvers_and_preconditioners/preconditioners/jacobi_preconditioner.h>
30#include <exadg/solvers_and_preconditioners/solvers/solver_data.h>
38template<
typename Operator,
typename VectorType>
39std::pair<double, double>
40estimate_eigenvalues_cg(Operator
const & underlying_operator,
42 bool const operator_is_singular,
43 unsigned int const eig_n_iter = 10000)
46 solution.reinit(inverse_diagonal);
47 rhs.reinit(inverse_diagonal,
true);
50 for(
unsigned int i = 0; i < rhs.locally_owned_size(); ++i)
51 rhs.local_element(i) = (double)rand() / RAND_MAX;
52 if(operator_is_singular)
53 dealii::VectorTools::subtract_mean_value(rhs);
55 dealii::SolverControl control(eig_n_iter, rhs.l2_norm() * 1e-5);
56 dealii::internal::EigenvalueTracker eigenvalue_tracker;
58 dealii::SolverCG<VectorType> solver(control);
60 solver.connect_eigenvalues_slot(std::bind(&dealii::internal::EigenvalueTracker::slot,
62 std::placeholders::_1),
69 solver.solve(underlying_operator, solution, rhs, preconditioner);
71 catch(dealii::SolverControl::NoConvergence &)
76 std::pair<double, double> eigenvalues_min_max;
77 if(eigenvalue_tracker.values.empty())
79 eigenvalues_min_max.first = eigenvalues_min_max.second = 1.;
83 eigenvalues_min_max.first = eigenvalue_tracker.values.front();
84 eigenvalues_min_max.second = eigenvalue_tracker.values.back();
87 return eigenvalues_min_max;
95 slot(std::vector<std::complex<double>>
const & eigenvalues)
100 std::vector<std::complex<double>> values;
108template<
typename Operator,
typename Preconditioner,
typename VectorType>
109std::vector<std::complex<double>>
110estimate_eigenvalues_gmres(Operator
const & underlying_operator,
111 Preconditioner
const & preconditioner,
120 dealii::ReductionControl solver_control(solver_data.max_iter,
122 solver_data.rel_tol);
124 typename dealii::SolverGMRES<VectorType>::AdditionalData additional_data;
125 additional_data.max_n_tmp_vectors = solver_data.max_krylov_size;
126 additional_data.right_preconditioning =
true;
127 dealii::SolverGMRES<VectorType> solver(solver_control, additional_data);
130 solver.connect_eigenvalues_slot(std::bind(&EigenvalueTracker::slot,
132 std::placeholders::_1),
137 solver.solve(underlying_operator, tmp, rhs, preconditioner);
139 catch(dealii::SolverControl::NoConvergence &)
144 std::vector<std::complex<double>>
const & eigenvalues = eigenvalue_tracker.values;
148 MPI_Comm
const & mpi_comm = solution.get_mpi_communicator();
149 if(dealii::Utilities::MPI::this_mpi_process(mpi_comm) == 0)
151 std::cout <<
"Approximate eigenvalues:\n";
152 for(
unsigned int j = 0; j < eigenvalues.size(); ++j)
154 std::cout <<
' ' << eigenvalues[j] <<
"\n";
Definition jacobi_preconditioner.h:35
Definition compute_eigenvalues.h:92
Definition solver_data.h:92