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 INCLUDE_EXADG_SOLVERS_AND_PRECONDITIONERS_UTIL_COMPUTE_EIGENVALUES_H_
23#define INCLUDE_EXADG_SOLVERS_AND_PRECONDITIONERS_UTIL_COMPUTE_EIGENVALUES_H_
24
25#include <deal.II/numerics/vector_tools_mean_value.h>
26
27namespace ExaDG
28{
29// manually compute eigenvalues for the coarsest level for proper setup of the
30// Chebyshev iteration
31template<typename Operator, typename VectorType>
32std::pair<double, double>
33compute_eigenvalues(Operator const & op,
34 VectorType const & inverse_diagonal,
35 bool const operator_is_singular,
36 unsigned int const eig_n_iter = 10000)
37{
38 VectorType solution, rhs;
39 solution.reinit(inverse_diagonal);
40 rhs.reinit(inverse_diagonal, true);
41 // NB: initialize rand in order to obtain "reproducible" results!
42 srand(1);
43 for(unsigned int i = 0; i < rhs.locally_owned_size(); ++i)
44 rhs.local_element(i) = (double)rand() / RAND_MAX;
45 if(operator_is_singular)
46 dealii::VectorTools::subtract_mean_value(rhs);
47
48 dealii::SolverControl control(eig_n_iter, rhs.l2_norm() * 1e-5);
49 dealii::internal::EigenvalueTracker eigenvalue_tracker;
50
51 dealii::SolverCG<VectorType> solver(control);
52
53 solver.connect_eigenvalues_slot(std::bind(&dealii::internal::EigenvalueTracker::slot,
54 &eigenvalue_tracker,
55 std::placeholders::_1));
56
57 JacobiPreconditioner<Operator> preconditioner(op, true /* initialize */);
58
59 try
60 {
61 solver.solve(op, solution, rhs, preconditioner);
62 }
63 catch(dealii::SolverControl::NoConvergence &)
64 {
65 }
66
67 std::pair<double, double> eigenvalues;
68 if(eigenvalue_tracker.values.empty())
69 {
70 eigenvalues.first = eigenvalues.second = 1.;
71 }
72 else
73 {
74 eigenvalues.first = eigenvalue_tracker.values.front();
75 eigenvalues.second = eigenvalue_tracker.values.back();
76 }
77
78 return eigenvalues;
79}
80
81template<typename Number>
83{
84public:
85 void
86 slot(const std::vector<Number> & eigenvalues)
87 {
88 values = eigenvalues;
89 }
90
91 std::vector<Number> values;
92};
93
94} // namespace ExaDG
95
96
97#endif /* INCLUDE_EXADG_SOLVERS_AND_PRECONDITIONERS_UTIL_COMPUTE_EIGENVALUES_H_ */
Definition driver.cpp:33
Definition compute_eigenvalues.h:83