Chi-Tech
petsc_utils_03_createKSP.cc
Go to the documentation of this file.
1#include "petsc_utils.h"
2
3#include <iomanip>
4
5#include "chi_runtime.h"
6#include "chi_log.h"
7
8//###################################################################
9/**Creates a common Krylov-solver setup.
10 *
11This is a macro for:
12\code
13PETScSolverSetup setup;
14
15KSPCreate(PETSC_COMM_WORLD,&setup.ksp);
16KSPSetOperators(setup.ksp,ref_matrix,ref_matrix);
17KSPSetType(setup.ksp,in_solver_type.c_str());
18
19KSPSetOptionsPrefix(setup.ksp,in_solver_name.c_str());
20
21KSPGetPC(setup.ksp,&setup.pc);
22PCSetType(setup.pc,in_preconditioner_type.c_str());
23
24KSPSetTolerances(setup.ksp,1.e-50,
25 in_relative_residual_tolerance,1.0e50,
26 in_maximum_iterations);
27KSPSetInitialGuessNonzero(setup.ksp,PETSC_TRUE);
28
29KSPMonitorSet(setup.ksp,&KSPMonitorRelativeToRHS,NULL,NULL);
30KSPSetConvergenceTest(setup.ksp,&RelativeResidualConvergenceTest,NULL,NULL);
31
32return setup;
33\endcode*/
36 Mat ref_matrix,
37 const std::string& in_solver_name,
38 const std::string& in_solver_type,
39 const std::string& in_preconditioner_type,
40 double in_relative_residual_tolerance,
41 int64_t in_maximum_iterations)
42{
43 PETScSolverSetup setup;
44
45 KSPCreate(PETSC_COMM_WORLD,&setup.ksp);
46 KSPSetOperators(setup.ksp,ref_matrix,ref_matrix);
47 KSPSetType(setup.ksp,in_solver_type.c_str());
48
49 KSPSetOptionsPrefix(setup.ksp,in_solver_name.c_str());
50
51 KSPGetPC(setup.ksp,&setup.pc);
52 PCSetType(setup.pc,in_preconditioner_type.c_str());
53
54 KSPSetTolerances(setup.ksp,1.e-50,
55 in_relative_residual_tolerance,1.0e50,
56 in_maximum_iterations);
57 KSPSetInitialGuessNonzero(setup.ksp,PETSC_TRUE);
58
59 KSPSetConvergenceTest(setup.ksp,&RelativeResidualConvergenceTest,
60 nullptr, nullptr);
61 KSPSetFromOptions(setup.ksp);
62
64 nullptr, nullptr);
65
66 return setup;
67}
68
69//###################################################################
70/**Relative Residual Convergence test. The test uses
71 * the L2-norm of the residual (\f$ ||b-Ax||_2 \f$), divided by
72 * by the L2-norm of the right hand side (\f$ ||b||_2 \f$) compared
73 * to a tolerance, \f$ \epsilon \f$.
74
75\f[
76 \frac{||b-Ax||_2}{||b||_2} < \epsilon
77\f]
78 *
79 * */
80PetscErrorCode
82 KSP ksp, PetscInt,
83 PetscReal rnorm,
84 KSPConvergedReason* convergedReason,
85 void* )
86{
87 //============================== Compute rhs norm
88 Vec Rhs;
89 KSPGetRhs(ksp,&Rhs);
90 double rhs_norm;
91 VecNorm(Rhs,NORM_2,&rhs_norm);
92 if (rhs_norm < 1.0e-12)
93 rhs_norm = 1.0;
94
95 //============================== Compute test criterion
96 double tol;
97 int64_t maxIts;
98 KSPGetTolerances(ksp, nullptr, &tol, nullptr, &maxIts);
99
100 double relative_residual = rnorm/rhs_norm;
101
102 if (relative_residual < tol)
103 *convergedReason = KSP_CONVERGED_RTOL;
104
105 return KSP_CONVERGED_ITERATING;
106}
107
108//###################################################################
109/**General monitor that print the residual norm relative to the
110 * right-hand side norm.*/
112 KSP ksp, PetscInt n, PetscReal rnorm, void*)
113{
114 Vec Rhs;
115 KSPGetRhs(ksp,&Rhs);
116 double rhs_norm;
117 VecNorm(Rhs,NORM_2,&rhs_norm);
118 if (rhs_norm < 1.0e-12)
119 rhs_norm = 1.0;
120
121 //Get solver name
122 const char* ksp_name;
123 KSPGetOptionsPrefix(ksp,&ksp_name);
124
125 //Default to this if ksp_name is NULL
126 const char NONAME_SOLVER[] = "NoName-Solver\0";
127
128 if (ksp_name == nullptr)
129 ksp_name = NONAME_SOLVER;
130
131 //Print message
132 std::stringstream buff;
133 buff
134 << ksp_name
135 << " iteration "
136 << std::setw(4) << n
137 << " - Residual "
138 << std::scientific << std::setprecision(7) << rnorm / rhs_norm
139 << std::endl;
140
141 Chi::log.Log() << buff.str();
142
143 return 0;
144}
145
146//###################################################################
147/**General monitor that print the residual norm relative to the
148 * right-hand side norm.*/
150 KSP ksp, PetscInt n, PetscReal rnorm, void*)
151{
152 //Get solver name
153 const char* ksp_name;
154 KSPGetOptionsPrefix(ksp,&ksp_name);
155
156 //Default to this if ksp_name is NULL
157 const char NONAME_SOLVER[] = "NoName-Solver\0";
158
159 if (ksp_name == nullptr)
160 ksp_name = NONAME_SOLVER;
161
162 //Print message
163 std::stringstream buff;
164 buff
165 << ksp_name
166 << " iteration "
167 << std::setw(4) << n
168 << " - Residual "
169 << std::scientific << std::setprecision(7) << rnorm
170 << std::endl;
171
172 Chi::log.Log() << buff.str();
173
174 return 0;
175}
static chi::ChiLog & log
Definition: chi_runtime.h:81
LogStream Log(LOG_LVL level=LOG_0)
Definition: chi_log.cc:35
PetscErrorCode KSPMonitorStraight(KSP ksp, PetscInt n, PetscReal rnorm, void *)
PetscErrorCode RelativeResidualConvergenceTest(KSP ksp, PetscInt n, PetscReal rnorm, KSPConvergedReason *convergedReason, void *monitordestroy)
PETScSolverSetup CreateCommonKrylovSolverSetup(Mat ref_matrix, const std::string &in_solver_name="KSPSolver", const std::string &in_solver_type=KSPGMRES, const std::string &in_preconditioner_type=PCNONE, double in_relative_residual_tolerance=1.0e-6, int64_t in_maximum_iterations=100)
PetscErrorCode KSPMonitorRelativeToRHS(KSP ksp, PetscInt n, PetscReal rnorm, void *)
struct _p_Mat * Mat
struct _p_Vec * Vec