Chi-Tech
NonLinearSolverPETSc.cc
Go to the documentation of this file.
2
3#include <petscsnes.h>
4
5#include "chi_log.h"
7
8namespace chi_math
9{
10
11template <>
13{
14 SNESDestroy(&nl_solver_);
15 VecDestroy(&x_);
16 VecDestroy(&r_);
17 MatDestroy(&J_);
18}
19
20template <>
21void NonLinearSolverPETSc::ApplyToleranceOptions()
22{
23 SNESSetTolerances(nl_solver_,
24 options_.nl_abs_tol_,
25 options_.nl_rel_tol_,
26 options_.nl_sol_tol_,
27 options_.nl_max_its_,
28 options_.nl_max_r_evaluations_);
29 SNESSetMaxLinearSolveFailures(nl_solver_, options_.l_max_failed_iterations_);
30 KSP ksp;
31 SNESGetKSP(nl_solver_, &ksp);
32 KSPSetTolerances(ksp,
33 options_.l_rel_tol_,
34 options_.l_abs_tol_,
35 options_.l_div_tol_,
36 options_.l_max_its_);
37 if (options_.l_method_ == "gmres")
38 {
39 KSPGMRESSetRestart(ksp, options_.l_gmres_restart_intvl_);
40 KSPGMRESSetBreakdownTolerance(ksp, options_.l_gmres_breakdown_tol_);
41 }
42 KSPSetInitialGuessNonzero(ksp, PETSC_FALSE);
43}
44template <>
45void NonLinearSolverPETSc::PreSetupCallback()
46{
47}
48
49template <>
50void NonLinearSolverPETSc::SetOptions()
51{
52}
53
54template <>
55void NonLinearSolverPETSc::SetSolverContext()
56{
57 SNESSetApplicationContext(nl_solver_, &(*context_ptr_));
58}
59
60template <>
61void NonLinearSolverPETSc::SetConvergenceTest()
62{
63}
64
65template <>
66void NonLinearSolverPETSc::SetMonitor()
67{
68}
69
70template <>
71void NonLinearSolverPETSc::SetPreconditioner()
72{
73}
74
75template <>
76void NonLinearSolverPETSc::PostSetupCallback()
77{
78}
79
80template <>
81void NonLinearSolverPETSc::Setup()
82{
83 if (IsSystemSet()) return;
84 this->PreSetupCallback();
85
86 SNESCreate(Chi::mpi.comm, &nl_solver_);
87
88 SNESSetOptionsPrefix(nl_solver_, solver_name_.c_str());
89
90 SNESSetType(nl_solver_, options_.petsc_snes_type_.c_str());
91 if (options_.nl_method_ == "LINEAR") SNESSetType(nl_solver_, SNESKSPONLY);
92 SNESLineSearch linesearch;
93 SNESGetLineSearch(nl_solver_, &linesearch);
94 SNESLineSearchSetType(linesearch, SNESLINESEARCHBT);
95
96 KSP ksp;
97 SNESGetKSP(nl_solver_, &ksp);
98 KSPSetType(ksp, options_.l_method_.c_str());
99
100 KSPSetOptionsPrefix(ksp, solver_name_.c_str());
101
102 this->ApplyToleranceOptions();
103
104 this->SetOptions();
105
106 this->SetSolverContext();
107 this->SetOptions();
108
109 this->SetSolverContext();
110 this->SetConvergenceTest();
111 this->SetMonitor();
112
113 this->SetSystemSize();
114 this->SetSystem();
115
116 this->SetFunction();
117 this->SetJacobian();
118
119 this->SetPreconditioner();
120
121 this->PostSetupCallback();
122 system_set_ = true;
123}
124
125template <>
126void NonLinearSolverPETSc::PreSolveCallback()
127{
128}
129
130template <>
131void NonLinearSolverPETSc::PostSolveCallback()
132{
133}
134
135template <>
136void NonLinearSolverPETSc::Solve()
137{
138 converged_ = false;
139 converged_reason_string_ = "Reason not obtained";
140 this->PreSolveCallback();
141 this->SetInitialGuess();
142
143 SNESSolve(nl_solver_, nullptr, x_);
144 this->PostSolveCallback();
145
146 SNESConvergedReason conv_reason;
147 SNESGetConvergedReason(nl_solver_, &conv_reason);
148
149 if (conv_reason > 0) converged_ = true;
150
151 const char* strreason;
152 SNESGetConvergedReasonString(nl_solver_, &strreason);
153
154 converged_reason_string_ = std::string(strreason);
155}
156
157template <>
158std::string NonLinearSolverPETSc::GetConvergedReasonString() const
159{
160 std::stringstream outstr;
161 if (converged_)
162 outstr << chi::StringStreamColor(chi::FG_GREEN) << std::string(10, ' ')
163 << "Converged " << converged_reason_string_
165 else
166 outstr << chi::StringStreamColor(chi::FG_RED) << std::string(10, ' ')
167 << "Convergence failure " << converged_reason_string_
169
170 return outstr.str();
171}
172
173} // namespace chi_math
static chi::MPI_Info & mpi
Definition: chi_runtime.h:78
std::string StringStreamColor(StringSteamColorCode code)