/home/runner/work/DiFfRG_current/DiFfRG_current/DiFfRG/include/DiFfRG/timestepping/linear_solver/ScaledGMRES.hh Source File#

DiFfRG: /home/runner/work/DiFfRG_current/DiFfRG_current/DiFfRG/include/DiFfRG/timestepping/linear_solver/ScaledGMRES.hh Source File
DiFfRG
Discretization Framework for functional Renormalization Group flows
ScaledGMRES.hh
Go to the documentation of this file.
1#pragma once
2
3// standard library
4#include <algorithm>
5#include <cmath>
6#include <stdexcept>
7#include <vector>
8
9// external libraries
10#include <deal.II/lac/precondition.h>
11
12// DiFfRG
16
17namespace DiFfRG
18{
19 template <typename SparseMatrixType, typename VectorType,
20 typename InnerSolver = GMRES<SparseMatrixType, VectorType, dealii::PreconditionIdentity>>
21 class ScaledLinearSolver : public AbstractLinearSolver<SparseMatrixType, VectorType>
22 {
23 public:
24 static constexpr bool performs_factorization = InnerSolver::performs_factorization;
25
26 ScaledLinearSolver() = default;
27
28 void init(const SparseMatrixType &matrix)
29 {
30 initialized = false;
31 build_scaling(matrix);
32 build_scaled_matrix(matrix);
34 initialized = true;
35 }
36
37 bool invert()
38 {
39 if (!initialized) throw std::runtime_error("ScaledLinearSolver::invert: solver not initialized");
40 return inner_solver.invert();
41 }
42
43 int solve(const VectorType &src, VectorType &dst, const double tol)
44 {
45 if (!initialized) throw std::runtime_error("ScaledLinearSolver::solve: solver not initialized");
46 if (src.size() != row_scale.size())
47 throw std::runtime_error("ScaledLinearSolver::solve: source vector size does not match matrix rows");
48
49 VectorType scaled_src(src);
50 VectorType scaled_dst(src);
51 scaled_dst = 0.;
52
53 for (std::size_t i = 0; i < scaled_src.size(); ++i)
54 scaled_src[i] *= row_scale[i];
55
56 const int solver_result = inner_solver.solve(scaled_src, scaled_dst, tol);
57
58 dst.reinit(src);
59 for (std::size_t i = 0; i < dst.size(); ++i)
60 dst[i] = col_scale[i] * scaled_dst[i];
61
62 return solver_result;
63 }
64
65 double estimate_scaled_rcond(const SparseMatrixType &, const unsigned int max_iterations = 5) const
66 requires(InnerSolver::performs_factorization)
67 {
68 return inner_solver.estimate_rcond(scaled_matrix, max_iterations);
69 }
70
71 private:
72 static double safe_inverse_sqrt(const double norm)
73 {
74 constexpr double min_norm = 1.e-300;
75 if (!std::isfinite(norm) || norm <= min_norm) return 1.;
76 return 1. / std::sqrt(norm);
77 }
78
79 void build_scaling(const SparseMatrixType &matrix)
80 {
81 row_scale.assign(matrix.m(), 0.);
82 col_scale.assign(matrix.n(), 0.);
83
84 for (std::size_t row = 0; row < matrix.m(); ++row) {
85 for (auto entry = matrix.begin(row); entry != matrix.end(row); ++entry) {
86 const auto column = entry->column();
87 const double value = std::abs(entry->value());
88 row_scale[row] = std::max(row_scale[row], value);
89 col_scale[column] = std::max(col_scale[column], value);
90 }
91 }
92
93 std::transform(row_scale.begin(), row_scale.end(), row_scale.begin(), safe_inverse_sqrt);
94 std::transform(col_scale.begin(), col_scale.end(), col_scale.begin(), safe_inverse_sqrt);
95 }
96
97 void build_scaled_matrix(const SparseMatrixType &matrix)
98 {
99 scaled_matrix.reinit(matrix.get_sparsity_pattern());
100 for (std::size_t row = 0; row < matrix.m(); ++row)
101 for (auto entry = matrix.begin(row); entry != matrix.end(row); ++entry)
102 scaled_matrix.add(row, entry->column(), row_scale[row] * entry->value() * col_scale[entry->column()]);
103 }
104
105 bool initialized = false;
106 SparseMatrixType scaled_matrix;
107 std::vector<double> row_scale;
108 std::vector<double> col_scale;
109 InnerSolver inner_solver;
110 };
111
112 template <typename SparseMatrixType, typename VectorType, typename PreconditionerType = dealii::PreconditionIdentity>
115
116 template <typename SparseMatrixType, typename VectorType>
118} // namespace DiFfRG
Definition abstract_linear_solver.hh:11
Definition ScaledGMRES.hh:22
static constexpr bool performs_factorization
Definition ScaledGMRES.hh:24
SparseMatrixType scaled_matrix
Definition ScaledGMRES.hh:106
std::vector< double > row_scale
Definition ScaledGMRES.hh:107
bool initialized
Definition ScaledGMRES.hh:105
void init(const SparseMatrixType &matrix)
Definition ScaledGMRES.hh:28
bool invert()
Definition ScaledGMRES.hh:37
int solve(const VectorType &src, VectorType &dst, const double tol)
Definition ScaledGMRES.hh:43
std::vector< double > col_scale
Definition ScaledGMRES.hh:108
InnerSolver inner_solver
Definition ScaledGMRES.hh:109
void build_scaled_matrix(const SparseMatrixType &matrix)
Definition ScaledGMRES.hh:97
double estimate_scaled_rcond(const SparseMatrixType &, const unsigned int max_iterations=5) const
Definition ScaledGMRES.hh:65
static double safe_inverse_sqrt(const double norm)
Definition ScaledGMRES.hh:72
void build_scaling(const SparseMatrixType &matrix)
Definition ScaledGMRES.hh:79
Definition complex_math.hh:10