OGS
MathLib::PETScLinearSolver Class Reference

Detailed Description

A class of linear solver based on PETSc routines.

All command-line options that are not recognized by OGS are passed on to PETSc, i.e., they potentially affect the linear solver. The linear solver options in the project file take precedence over the command-line options, because the former are processed at a later stage.

Definition at line 37 of file PETScLinearSolver.h.

#include <PETScLinearSolver.h>

Public Member Functions

 PETScLinearSolver (std::string const &prefix, std::string const &petsc_options)
 
 ~PETScLinearSolver ()
 
bool solve (PETScMatrix &A, PETScVector &b, PETScVector &x)
 
PetscInt getNumberOfIterations () const
 Get number of iterations.
 
double getElapsedTime () const
 Get elapsed wall clock time.
 
bool canSolveRectangular () const
 Get, if the solver can handle rectangular equation systems.
 

Private Member Functions

bool canSolverHandleRectangular (std::string_view ksp_type)
 

Private Attributes

KSP solver_
 Solver type.
 
PC pc_
 Preconditioner type.
 
bool can_solve_rectangular_ = false
 
double elapsed_ctime_ = 0.0
 Clock time.
 

Constructor & Destructor Documentation

◆ PETScLinearSolver()

MathLib::PETScLinearSolver::PETScLinearSolver ( std::string const & prefix,
std::string const & petsc_options )

Constructor

Parameters
prefixName used to distinguish the options in the command line for this solver. It can be the name of the PDE that owns an instance of this class.
petsc_optionsPETSc options string which is passed to PETSc lib and inserted in the PETSc option database (see https://petsc.org/release/manualpages/Sys/PetscOptionsInsertString/).

Definition at line 23 of file PETScLinearSolver.cpp.

25{
26#if PETSC_VERSION_LT(3, 7, 0)
27 PetscOptionsInsertString(petsc_options.c_str());
28#else
29 PetscOptionsInsertString(nullptr, petsc_options.c_str());
30#endif
31
32 KSPCreate(PETSC_COMM_WORLD, &solver_);
33
34 KSPGetPC(solver_, &pc_);
35
36 if (!prefix.empty())
37 {
38 KSPSetOptionsPrefix(solver_, prefix.c_str());
39 }
40
41 KSPSetInitialGuessNonzero(solver_, PETSC_TRUE);
42 KSPSetFromOptions(solver_); // set run-time options
43
44 KSPType ksp_type;
45 KSPGetType(solver_, &ksp_type);
47}
PC pc_
Preconditioner type.
bool canSolverHandleRectangular(std::string_view ksp_type)

References can_solve_rectangular_, canSolverHandleRectangular(), pc_, and solver_.

◆ ~PETScLinearSolver()

MathLib::PETScLinearSolver::~PETScLinearSolver ( )
inline

Definition at line 52 of file PETScLinearSolver.h.

52{ KSPDestroy(&solver_); }

References solver_.

Member Function Documentation

◆ canSolveRectangular()

bool MathLib::PETScLinearSolver::canSolveRectangular ( ) const
inline

Get, if the solver can handle rectangular equation systems.

Definition at line 68 of file PETScLinearSolver.h.

68{ return can_solve_rectangular_; }

References can_solve_rectangular_.

◆ canSolverHandleRectangular()

bool MathLib::PETScLinearSolver::canSolverHandleRectangular ( std::string_view ksp_type)
inlineprivate

Definition at line 71 of file PETScLinearSolver.h.

72 {
73 // List of KSP types that can handle rectangular matrices
74 constexpr auto rectangular_solvers = std::to_array<std::string_view>(
75 {KSPGMRES, KSPFGMRES, KSPBCGS, KSPBCGSL, KSPTFQMR, KSPCGS});
76
77 return std::ranges::any_of(rectangular_solvers,
78 [&](const auto& solver)
79 { return solver == ksp_type; });
80 }

Referenced by PETScLinearSolver().

◆ getElapsedTime()

double MathLib::PETScLinearSolver::getElapsedTime ( ) const
inline

Get elapsed wall clock time.

Definition at line 65 of file PETScLinearSolver.h.

65{ return elapsed_ctime_; }
double elapsed_ctime_
Clock time.

References elapsed_ctime_.

◆ getNumberOfIterations()

PetscInt MathLib::PETScLinearSolver::getNumberOfIterations ( ) const
inline

Get number of iterations.

Definition at line 57 of file PETScLinearSolver.h.

58 {
59 PetscInt its = 0;
60 KSPGetIterationNumber(solver_, &its);
61 return its;
62 }

References solver_.

◆ solve()

bool MathLib::PETScLinearSolver::solve ( PETScMatrix & A,
PETScVector & b,
PETScVector & x )

Definition at line 49 of file PETScLinearSolver.cpp.

50{
51 BaseLib::RunTime wtimer;
52 wtimer.start();
53
54// define TEST_MEM_PETSC
55#ifdef TEST_MEM_PETSC
56 PetscLogDouble mem1, mem2;
57 PetscMemoryGetCurrentUsage(&mem1);
58#endif
59
60 KSPNormType norm_type;
61 KSPGetNormType(solver_, &norm_type);
62 const char* ksp_type;
63 const char* pc_type;
64 KSPGetType(solver_, &ksp_type);
65 PCGetType(pc_, &pc_type);
66
67 PetscPrintf(PETSC_COMM_WORLD,
68 "\n================================================");
69 PetscPrintf(PETSC_COMM_WORLD,
70 "\nLinear solver %s with %s preconditioner using %s", ksp_type,
71 pc_type, KSPNormTypes[norm_type]);
72
73 KSPSetOperators(solver_, A.getRawMatrix(), A.getRawMatrix());
74
75 KSPSolve(solver_, b.getRawVector(), x.getRawVector());
76
77 KSPConvergedReason reason;
78 KSPGetConvergedReason(solver_, &reason);
79
80 bool converged = true;
81 if (reason > 0)
82 {
83 PetscInt its;
84 KSPGetIterationNumber(solver_, &its);
85 PetscPrintf(PETSC_COMM_WORLD, "\nconverged in %d iterations", its);
86 switch (reason)
87 {
88 case KSP_CONVERGED_RTOL:
89 PetscPrintf(PETSC_COMM_WORLD,
90 " (relative convergence criterion fulfilled).");
91 break;
92 case KSP_CONVERGED_ATOL:
93 PetscPrintf(PETSC_COMM_WORLD,
94 " (absolute convergence criterion fulfilled).");
95 break;
96 default:
97 PetscPrintf(PETSC_COMM_WORLD, ".");
98 }
99
100 PetscPrintf(PETSC_COMM_WORLD,
101 "\n================================================\n");
102 }
103 else if (reason == KSP_DIVERGED_ITS)
104 {
105 PetscPrintf(PETSC_COMM_WORLD,
106 "\nWarning: maximum number of iterations reached.\n");
107 }
108 else
109 {
110 converged = false;
111 if (reason == KSP_DIVERGED_INDEFINITE_PC)
112 {
113 PetscPrintf(PETSC_COMM_WORLD,
114 "\nDivergence because of indefinite preconditioner,");
115 PetscPrintf(PETSC_COMM_WORLD,
116 "\nTry to run again with "
117 "-pc_factor_shift_positive_definite option.\n");
118 }
119 else if (reason == KSP_DIVERGED_BREAKDOWN_BICG)
120 {
121 PetscPrintf(PETSC_COMM_WORLD,
122 "\nKSPBICG method was detected so the method could not "
123 "continue to enlarge the Krylov space.");
124 PetscPrintf(PETSC_COMM_WORLD,
125 "\nTry to run again with another solver.\n");
126 }
127 else if (reason == KSP_DIVERGED_NONSYMMETRIC)
128 {
129 PetscPrintf(PETSC_COMM_WORLD,
130 "\nMatrix or preconditioner is unsymmetric but KSP "
131 "requires symmetric.\n");
132 }
133 else
134 {
135 PetscPrintf(PETSC_COMM_WORLD,
136 "\nDivergence detected, use command option "
137 "-ksp_monitor or -log_summary to check the details.\n");
138 }
139 }
140
141#ifdef TEST_MEM_PETSC
142 PetscMemoryGetCurrentUsage(&mem2);
143 PetscPrintf(
144 PETSC_COMM_WORLD,
145 "###Memory usage by solver. Before: %f After: %f Increase: %d\n", mem1,
146 mem2, (int)(mem2 - mem1));
147#endif
148
149 elapsed_ctime_ += wtimer.elapsed();
150
151 return converged;
152}
Count the running time.
Definition RunTime.h:29
double elapsed() const
Get the elapsed time in seconds.
Definition RunTime.h:42
void start()
Start the timer.
Definition RunTime.h:32

References BaseLib::RunTime::elapsed(), elapsed_ctime_, MathLib::PETScMatrix::getRawMatrix(), MathLib::PETScVector::getRawVector(), pc_, solver_, and BaseLib::RunTime::start().

Member Data Documentation

◆ can_solve_rectangular_

bool MathLib::PETScLinearSolver::can_solve_rectangular_ = false
private

Definition at line 85 of file PETScLinearSolver.h.

Referenced by PETScLinearSolver(), and canSolveRectangular().

◆ elapsed_ctime_

double MathLib::PETScLinearSolver::elapsed_ctime_ = 0.0
private

Clock time.

Definition at line 87 of file PETScLinearSolver.h.

Referenced by getElapsedTime(), and solve().

◆ pc_

PC MathLib::PETScLinearSolver::pc_
private

Preconditioner type.

Definition at line 83 of file PETScLinearSolver.h.

Referenced by PETScLinearSolver(), and solve().

◆ solver_

KSP MathLib::PETScLinearSolver::solver_
private

Solver type.

Definition at line 82 of file PETScLinearSolver.h.

Referenced by PETScLinearSolver(), ~PETScLinearSolver(), getNumberOfIterations(), and solve().


The documentation for this class was generated from the following files: