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

DiFfRG: /home/runner/work/DiFfRG_current/DiFfRG_current/DiFfRG/include/DiFfRG/timestepping/linear_solver/PETScDirect.hh Source File
DiFfRG
Discretization Framework for functional Renormalization Group flows
PETScDirect.hh
Go to the documentation of this file.
1#pragma once
2
3// external libraries
4#include <deal.II/base/config.h>
5
6// MUMPS is what makes a *distributed* direct solve possible; it is an opt-in PETSc package
7// (-DPETSC_MUMPS=ON), and deal.II reports whether PETSc actually has it. Note that deal.II
8// declares PETScWrappers::SparseDirectMUMPS unconditionally and only fails at runtime, so
9// gating here is what turns "wrong answer at 3am" into "does not compile".
10#if defined(DEAL_II_WITH_PETSC) && defined(DEAL_II_PETSC_WITH_MUMPS)
11
12#include <deal.II/lac/petsc_solver.h>
13#include <deal.II/lac/solver_control.h>
14
15// standard library
16#include <memory>
17#include <stdexcept>
18
19// DiFfRG
21
22namespace DiFfRG
23{
43 template <typename SparseMatrixType, typename VectorType>
44 class PETScDirect : public AbstractLinearSolver<SparseMatrixType, VectorType>
45 {
46 public:
47 static constexpr bool performs_factorization = false;
48
49 PETScDirect() : matrix(nullptr) {}
50
51 void init(const SparseMatrixType &matrix)
52 {
53 this->matrix = &matrix;
54 // New operator => the cached factorization is stale. Drop it; the next solve rebuilds.
55 solver.reset();
56 control.reset();
57 }
58
59 bool invert() { return false; }
60
61 int solve(const VectorType &src, VectorType &dst, const double tol)
62 {
63 if (!matrix) throw std::runtime_error("PETScDirect::solve: matrix not initialized");
64
65 if (!solver) {
66 // A direct solve needs no iteration budget; MUMPS returns in one KSP step. The
67 // tolerance is carried anyway so a caller tightening it is not silently ignored.
68 control = std::make_unique<dealii::SolverControl>(1, tol);
69 solver = std::make_unique<dealii::PETScWrappers::SparseDirectMUMPS>(*control);
70 } else {
71 control->set_tolerance(tol);
72 }
73
74 try {
75 solver->solve(*matrix, dst, src);
76 } catch (std::exception &e) {
77 std::cerr << "PETSc MUMPS direct solver failed: " << e.what() << std::endl;
78 throw;
79 }
80
81 return control->last_step();
82 }
83
84 private:
85 const SparseMatrixType *matrix;
86 // SparseDirectMUMPS holds its SolverControl by reference, so the control must outlive it;
87 // declaration order here is load-bearing (members are destroyed in reverse).
88 std::unique_ptr<dealii::SolverControl> control;
89 std::unique_ptr<dealii::PETScWrappers::SparseDirectMUMPS> solver;
90 };
91} // namespace DiFfRG
92
93#endif // DEAL_II_WITH_PETSC && DEAL_II_PETSC_WITH_MUMPS
Definition complex_math.hh:10