Chi-Tech
diffusion_03_solve.cc
Go to the documentation of this file.
1#include "diffusion.h"
2
5
7
8#include "chi_runtime.h"
9#include "chi_log.h"
10
11// ###################################################################
12/**Solves the system and stores the local solution in the vector provide.
13 *
14 * \param solution Vector in to which the solution will be parsed.
15 * \param use_initial_guess bool [Default:False] Flag, when set, will
16 * use the values of the output solution as initial guess.*/
18 std::vector<double>& solution, bool use_initial_guess /*=false*/)
19{
20 const std::string fname = "lbs::acceleration::DiffusionMIPSolver::Solve";
21 Vec x;
22 VecDuplicate(rhs_, &x);
23 VecSet(x, 0.0);
24
25 if (not use_initial_guess) KSPSetInitialGuessNonzero(ksp_, PETSC_FALSE);
26 else
27 KSPSetInitialGuessNonzero(ksp_, PETSC_TRUE);
28
29 KSPSetTolerances(ksp_,
32 1.0e50,
34
36 {
37 PetscBool symmetry = PETSC_FALSE;
38 MatIsSymmetric(A_, 1.0e-6, &symmetry);
39 if (symmetry == PETSC_FALSE)
40 throw std::logic_error(fname + ":Symmetry check failed");
41 }
42
43 if (options.verbose)
44 {
45 using namespace chi_math::PETScUtils;
46 KSPSetConvergenceTest(
47 ksp_, &RelativeResidualConvergenceTest, nullptr, nullptr);
48
49 KSPMonitorSet(ksp_, &KSPMonitorRelativeToRHS, nullptr, nullptr);
50
51 double rhs_norm;
52 VecNorm(rhs_, NORM_2, &rhs_norm);
53 Chi::log.Log() << "RHS-norm " << rhs_norm;
54 }
55
56 if (use_initial_guess)
57 {
58 double* x_raw;
59 VecGetArray(x, &x_raw);
60 size_t k = 0;
61 for (const auto& value : solution)
62 x_raw[k++] = value;
63 VecRestoreArray(x, &x_raw);
64 }
65
66 //============================================= Solve
67 KSPSolve(ksp_, rhs_, x);
68
69 //============================================= Print convergence info
70 if (options.verbose)
71 {
72 double sol_norm;
73 VecNorm(x, NORM_2, &sol_norm);
74 Chi::log.Log() << "Solution-norm " << sol_norm;
75
76 using namespace chi_physics;
77 KSPConvergedReason reason;
78 KSPGetConvergedReason(ksp_, &reason);
79
80 Chi::log.Log() << "Convergence Reason: "
82 }
83
84 //============================================= Transfer petsc solution to
85 // vector
87 {
90 }
91 else
92 sdm_.LocalizePETScVector(x, solution, uk_man_);
93
94 //============================================= Cleanup x
95 VecDestroy(&x);
96}
97
98// ###################################################################
99/**Solves the system and stores the local solution in the vector provide.
100 *
101 * \param petsc_solution Vector in to which the solution will be parsed.
102 * \param use_initial_guess bool [Default:False] Flag, when set, will
103 * use the values of the output solution as initial guess.*/
105 Vec petsc_solution, bool use_initial_guess /*=false*/)
106{
107 const std::string fname = "lbs::acceleration::DiffusionMIPSolver::Solve";
108 Vec x;
109 VecDuplicate(rhs_, &x);
110 VecSet(x, 0.0);
111
112 if (not use_initial_guess) KSPSetInitialGuessNonzero(ksp_, PETSC_FALSE);
113 else
114 KSPSetInitialGuessNonzero(ksp_, PETSC_TRUE);
115
116 KSPSetTolerances(ksp_,
117 options.residual_tolerance,
118 options.residual_tolerance,
119 1.0e50,
120 options.max_iters);
121
122 if (options.perform_symmetry_check)
123 {
124 PetscBool symmetry = PETSC_FALSE;
125 MatIsSymmetric(A_, 1.0e-6, &symmetry);
126 if (symmetry == PETSC_FALSE)
127 throw std::logic_error(fname + ":Symmetry check failed");
128 }
129
130 if (options.verbose)
131 {
132 using namespace chi_math::PETScUtils;
133 KSPSetConvergenceTest(
134 ksp_, &RelativeResidualConvergenceTest, nullptr, nullptr);
135
136 KSPMonitorSet(ksp_, &KSPMonitorRelativeToRHS, nullptr, nullptr);
137
138 double rhs_norm;
139 VecNorm(rhs_, NORM_2, &rhs_norm);
140 Chi::log.Log() << "RHS-norm " << rhs_norm;
141 }
142
143 if (use_initial_guess) { VecCopy(petsc_solution, x); }
144
145 //============================================= Solve
146 KSPSolve(ksp_, rhs_, x);
147
148 //============================================= Print convergence info
149 if (options.verbose)
150 {
151 double sol_norm;
152 VecNorm(x, NORM_2, &sol_norm);
153 Chi::log.Log() << "Solution-norm " << sol_norm;
154
155 using namespace chi_physics;
156 KSPConvergedReason reason;
157 KSPGetConvergedReason(ksp_, &reason);
158
159 Chi::log.Log() << "Convergence Reason: "
161 }
162
163 //============================================= Transfer petsc solution to
164 // vector
165 VecCopy(x, petsc_solution);
166
167 //============================================= Cleanup x
168 VecDestroy(&x);
169}
static chi::ChiLog & log
Definition: chi_runtime.h:81
LogStream Log(LOG_LVL level=LOG_0)
Definition: chi_log.cc:35
virtual void LocalizePETScVectorWithGhosts(Vec petsc_vector, std::vector< double > &local_vector, const UnknownManager &unknown_manager) const
virtual void LocalizePETScVector(Vec petsc_vector, std::vector< double > &local_vector, const UnknownManager &unknown_manager) const
struct lbs::acceleration::DiffusionSolver::Options options
const chi_math::SpatialDiscretization & sdm_
Definition: diffusion.h:39
void Solve(std::vector< double > &solution, bool use_initial_guess=false)
const chi_math::UnknownManager uk_man_
Definition: diffusion.h:40
PetscErrorCode RelativeResidualConvergenceTest(KSP ksp, PetscInt n, PetscReal rnorm, KSPConvergedReason *convergedReason, void *monitordestroy)
PetscErrorCode KSPMonitorRelativeToRHS(KSP ksp, PetscInt n, PetscReal rnorm, void *)
std::string GetPETScConvergedReasonstring(KSPConvergedReason reason)
struct _p_Vec * Vec
double residual_tolerance
Residual tol. relative to rhs.
Definition: diffusion.h:60
bool perform_symmetry_check
For debugging only (very expensive)
Definition: diffusion.h:63