36 #include "SimpleNewtonNonlinearSolver.hpp"
47 for (
unsigned i=1; i<=12; i++)
58 #
if (PETSC_VERSION_MAJOR==3 && PETSC_VERSION_MINOR>=5)
59 PetscErrorCode (*pComputeJacobian)(SNES,
Vec,
Mat,
Mat,
void*),
61 PetscErrorCode (*pComputeJacobian)(SNES,
Vec,
Mat*,
Mat*,MatStructure*,
void*),
68 VecGetSize(initialGuess, &size);
71 VecDuplicate(initialGuess, ¤t_solution);
72 VecCopy(initialGuess, current_solution);
75 LinearSystem linear_system(current_solution, fill,
false);
77 (*pComputeResidual)(
nullptr, current_solution, linear_system.
rGetRhsVector(), pContext);
81 VecNorm(linear_system.
rGetRhsVector(), NORM_2, &residual_norm);
82 double scaled_residual_norm = residual_norm/size;
86 std::cout <<
"Newton's method:\n Initial ||residual||/N = " << scaled_residual_norm
87 <<
"\n Attempting to solve to tolerance " <<
mTolerance <<
"..\n";
90 double old_scaled_residual_norm;
97 old_scaled_residual_norm = scaled_residual_norm;
100 #if (PETSC_VERSION_MAJOR==3 && PETSC_VERSION_MINOR>=5)
101 (*pComputeJacobian)(
nullptr, current_solution, (linear_system.
rGetLhsMatrix()),
nullptr, pContext);
103 (*pComputeJacobian)(
nullptr, current_solution, &(linear_system.
rGetLhsMatrix()),
nullptr,
nullptr, pContext);
106 Vec negative_update = linear_system.
Solve();
110 VecDuplicate(initialGuess, &test_vec);
112 double best_damping_factor = 1.0;
113 double best_scaled_residual = 1e20;
123 (*pComputeResidual)(
nullptr, test_vec, linear_system.
rGetRhsVector(), pContext);
124 VecNorm(linear_system.
rGetRhsVector(), NORM_2, &residual_norm);
125 scaled_residual_norm = residual_norm/size;
127 if (scaled_residual_norm < best_scaled_residual)
129 best_scaled_residual = scaled_residual_norm;
136 if (best_scaled_residual > old_scaled_residual_norm)
143 EXCEPTION(
"Iteration " << counter <<
", unable to find damping factor such that residual decreases in update direction");
148 std::cout <<
" Best damping factor = " << best_damping_factor <<
"\n";
153 scaled_residual_norm = best_scaled_residual;
158 (*pComputeResidual)(
nullptr, current_solution, linear_system.
rGetRhsVector(), pContext);
162 std::cout <<
" Iteration " << counter <<
": ||residual||/N = " << scaled_residual_norm <<
"\n";
168 std::cout <<
" ..solved!\n\n";
171 return current_solution;
176 assert(tolerance > 0);
SimpleNewtonNonlinearSolver()
Vec Solve(Vec lhsGuess=nullptr)
#define EXCEPTION(message)
virtual ~SimpleNewtonNonlinearSolver()
virtual Vec Solve(PetscErrorCode(*pComputeResidual)(SNES, Vec, Vec, void *), PetscErrorCode(*pComputeJacobian)(SNES, Vec, Mat *, Mat *, MatStructure *, void *), Vec initialGuess, unsigned fill, void *pContext)
std::vector< double > mTestDampingValues
void SetTolerance(double tolerance)