ExaDG
Loading...
Searching...
No Matches
compute_eigenvalues.h
1/* ______________________________________________________________________
2 *
3 * ExaDG - High-Order Discontinuous Galerkin for the Exa-Scale
4 *
5 * Copyright (C) 2021 by the ExaDG authors
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 * ______________________________________________________________________
20 */
21
22#ifndef EXADG_SOLVERS_AND_PRECONDITIONERS_UTILITIES_COMPUTE_EIGENVALUES_H_
23#define EXADG_SOLVERS_AND_PRECONDITIONERS_UTILITIES_COMPUTE_EIGENVALUES_H_
24
25// deal.II
26#include <deal.II/numerics/vector_tools_mean_value.h>
27
28namespace ExaDG
29{
30// manually compute eigenvalues for the coarsest level for proper setup of the
31// Chebyshev iteration
32template<typename Operator, typename VectorType>
33std::pair<double, double>
34compute_eigenvalues(Operator const & op,
35 VectorType const & inverse_diagonal,
36 bool const operator_is_singular,
37 unsigned int const eig_n_iter = 10000)
38{
39 VectorType solution, rhs;
40 solution.reinit(inverse_diagonal);
41 rhs.reinit(inverse_diagonal, true);
42 // NB: initialize rand in order to obtain "reproducible" results!
43 srand(1);
44 for(unsigned int i = 0; i < rhs.locally_owned_size(); ++i)
45 rhs.local_element(i) = (double)rand() / RAND_MAX;
46 if(operator_is_singular)
47 dealii::VectorTools::subtract_mean_value(rhs);
48
49 dealii::SolverControl control(eig_n_iter, rhs.l2_norm() * 1e-5);
50 dealii::internal::EigenvalueTracker eigenvalue_tracker;
51
52 dealii::SolverCG<VectorType> solver(control);
53
54 solver.connect_eigenvalues_slot(std::bind(&dealii::internal::EigenvalueTracker::slot,
55 &eigenvalue_tracker,
56 std::placeholders::_1));
57
58 JacobiPreconditioner<Operator> preconditioner(op, true /* initialize */);
59
60 try
61 {
62 solver.solve(op, solution, rhs, preconditioner);
63 }
64 catch(dealii::SolverControl::NoConvergence &)
65 {
66 }
67
68 std::pair<double, double> eigenvalues;
69 if(eigenvalue_tracker.values.empty())
70 {
71 eigenvalues.first = eigenvalues.second = 1.;
72 }
73 else
74 {
75 eigenvalues.first = eigenvalue_tracker.values.front();
76 eigenvalues.second = eigenvalue_tracker.values.back();
77 }
78
79 return eigenvalues;
80}
81
82template<typename Number>
84{
85public:
86 void
87 slot(const std::vector<Number> & eigenvalues)
88 {
89 values = eigenvalues;
90 }
91
92 std::vector<Number> values;
93};
94
95} // namespace ExaDG
96
97#endif /* EXADG_SOLVERS_AND_PRECONDITIONERS_UTILITIES_COMPUTE_EIGENVALUES_H_ */
Definition jacobi_preconditioner.h:35
Definition driver.cpp:33
Definition compute_eigenvalues.h:84