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

DiFfRG: /home/runner/work/DiFfRG_current/DiFfRG_current/DiFfRG/include/DiFfRG/timestepping/linear_solver/UMFPack.hh Source File
DiFfRG
Discretization Framework for functional Renormalization Group flows
UMFPack.hh
Go to the documentation of this file.
1#pragma once
2
3// external libraries
4#include <deal.II/lac/sparse_direct.h>
5
6// DiFfRG
9
10namespace DiFfRG
11{
12 template <typename SparseMatrixType, typename VectorType>
13 class UMFPack : public AbstractLinearSolver<SparseMatrixType, VectorType>
14 {
15 public:
16 static constexpr bool performs_factorization = true;
17
18 UMFPack() : matrix(nullptr) {}
19
20 void init(const SparseMatrixType &matrix) { this->matrix = &matrix; }
21
22 bool invert()
23 {
24 if (!matrix) throw std::runtime_error("UMFPack::invert: matrix not initialized");
25 solver.initialize(*matrix);
26 return true;
27 }
28
29 int solve(const VectorType &src, VectorType &dst, const double)
30 {
31 if (!matrix) throw std::runtime_error("UMFPack::solve: matrix not initialized");
32 solver.vmult(dst, src);
33 return -1;
34 }
35
36 void solve_transpose(const VectorType &src, VectorType &dst) const
37 {
38 if (!matrix) throw std::runtime_error("UMFPack::solve_transpose: matrix not initialized");
39 dst = src;
40 solver.solve(dst, true);
41 }
42
43 double estimate_rcond(const SparseMatrixType &input_matrix, const unsigned int max_iterations = 5) const
44 {
45 if (!matrix) throw std::runtime_error("UMFPack::estimate_rcond: matrix not initialized");
46 const double one_norm = internal::matrix_one_norm(input_matrix);
47 if (!(one_norm > 0.) || !std::isfinite(one_norm)) return std::numeric_limits<double>::quiet_NaN();
48
49 const auto solve_direct = [&](const VectorType &src, VectorType &dst) { solver.vmult(dst, src); };
50 const auto solve_direct_transpose = [&](const VectorType &src, VectorType &dst) {
51 dst = src;
52 solver.solve(dst, true);
53 };
54 const double inverse_one_norm = internal::estimate_inverse_one_norm<VectorType>(
55 input_matrix.m(), solve_direct, solve_direct_transpose, max_iterations);
56 if (!(inverse_one_norm > 0.) || !std::isfinite(inverse_one_norm)) return std::numeric_limits<double>::quiet_NaN();
57 return std::clamp(1. / (one_norm * inverse_one_norm), 0., 1.);
58 }
59
60 double estimate_scaled_rcond(const SparseMatrixType &input_matrix, const unsigned int max_iterations = 5) const
61 {
62 if (!matrix) throw std::runtime_error("UMFPack::estimate_scaled_rcond: matrix not initialized");
63
64 std::vector<double> row_scale, column_scale;
65 double scaled_one_norm = 0.;
66 internal::build_maximum_equilibration(input_matrix, row_scale, column_scale, scaled_one_norm);
67 if (!(scaled_one_norm > 0.) || !std::isfinite(scaled_one_norm)) return std::numeric_limits<double>::quiet_NaN();
68
69 const auto solve_scaled = [&](const VectorType &src, VectorType &dst) {
70 VectorType rhs(src), solution(src);
71 for (std::size_t i = 0; i < rhs.size(); ++i)
72 rhs[i] /= row_scale[i];
73 solver.vmult(solution, rhs);
74 dst.reinit(solution);
75 for (std::size_t i = 0; i < solution.size(); ++i)
76 dst[i] = solution[i] / column_scale[i];
77 };
78 const auto solve_scaled_transpose = [&](const VectorType &src, VectorType &dst) {
79 VectorType rhs(src), solution(src);
80 for (std::size_t i = 0; i < rhs.size(); ++i)
81 rhs[i] /= column_scale[i];
82 solution = rhs;
83 solver.solve(solution, true);
84 dst.reinit(solution);
85 for (std::size_t i = 0; i < solution.size(); ++i)
86 dst[i] = solution[i] / row_scale[i];
87 };
88
89 const double inverse_one_norm = internal::estimate_inverse_one_norm<VectorType>(
90 input_matrix.m(), solve_scaled, solve_scaled_transpose, max_iterations);
91 if (!(inverse_one_norm > 0.) || !std::isfinite(inverse_one_norm)) return std::numeric_limits<double>::quiet_NaN();
92 return std::clamp(1. / (scaled_one_norm * inverse_one_norm), 0., 1.);
93 }
94
95 private:
96 const SparseMatrixType *matrix;
97 dealii::SparseDirectUMFPACK solver;
98 };
99} // namespace DiFfRG
Definition abstract_linear_solver.hh:11
Definition UMFPack.hh:14
dealii::SparseDirectUMFPACK solver
Definition UMFPack.hh:97
void init(const SparseMatrixType &matrix)
Definition UMFPack.hh:20
double estimate_scaled_rcond(const SparseMatrixType &input_matrix, const unsigned int max_iterations=5) const
Definition UMFPack.hh:60
static constexpr bool performs_factorization
Definition UMFPack.hh:16
int solve(const VectorType &src, VectorType &dst, const double)
Definition UMFPack.hh:29
bool invert()
Definition UMFPack.hh:22
void solve_transpose(const VectorType &src, VectorType &dst) const
Definition UMFPack.hh:36
double estimate_rcond(const SparseMatrixType &input_matrix, const unsigned int max_iterations=5) const
Definition UMFPack.hh:43
UMFPack()
Definition UMFPack.hh:18
const SparseMatrixType * matrix
Definition UMFPack.hh:96
double matrix_one_norm(const MatrixType &matrix)
Definition condition_estimate.hh:11
void build_maximum_equilibration(const MatrixType &matrix, std::vector< double > &row_scale, std::vector< double > &column_scale, double &scaled_one_norm)
Definition condition_estimate.hh:61
double estimate_inverse_one_norm(const std::size_t n, Solve &&solve, SolveTranspose &&solve_transpose, const unsigned int max_iterations=5)
Definition condition_estimate.hh:21
Definition complex_math.hh:10