Go to the documentation of this file.
19 #include "libmesh/diff_system.h"
20 #include "libmesh/dof_map.h"
21 #include "libmesh/libmesh_logging.h"
22 #include "libmesh/linear_solver.h"
23 #include "libmesh/newton_solver.h"
24 #include "libmesh/numeric_vector.h"
25 #include "libmesh/sparse_matrix.h"
40 Real & current_residual,
46 if ((current_residual < last_residual) ||
61 (current_residual > last_residual &&
68 substepdivision = std::min(0.5, last_residual/current_residual);
69 substepdivision = std::max(substepdivision, tol*2.);
72 substepdivision = 0.5;
74 newton_iterate.
add (bx * (1.-substepdivision),
76 newton_iterate.
close();
77 bx *= substepdivision;
89 current_residual = rhs.
l2_norm();
92 << current_residual << std::endl;
96 (current_residual > last_residual)))
103 libmesh_convergence_failure();
123 Real x = bx, w = bx, v = bx;
126 Real fx = current_residual,
127 fw = current_residual,
128 fv = current_residual;
131 const unsigned int max_i = 20;
136 for (
unsigned int i=1; i <= max_i; i++)
138 Real xm = (ax+cx)*0.5;
140 Real tol2 = 2.0 * tol1;
143 if (
std::abs(x-xm) <= (tol2 - 0.5 * (cx - ax)))
151 Real r = (x-w)*(fx-fv);
152 Real q = (x-v)*(fx-fw);
153 Real p = (x-v)*q-(x-w)*r;
164 e = x >= xm ? ax-x : cx-x;
165 d = golden_ratio * e;
171 if (x+d-ax < tol2 || cx-(x+d) < tol2)
172 d =
SIGN(tol1, xm - x);
178 e = x >= xm ? ax-x : cx-x;
179 d = golden_ratio * e;
185 newton_iterate.
add (bx - u, linear_solution);
186 newton_iterate.
close();
209 fv = fw; fw = fx; fx = fu;
217 if (fu <= fw || w == x)
222 else if (fu <= fv || v == x || v == w)
231 libMesh::out <<
"Warning! Too many iterations used in Brent line search!"
239 require_residual_reduction(true),
240 require_finite_residual(true),
241 brent_line_search(true),
242 track_linear_convergence(false),
244 linear_tolerance_multiplier(1e-3),
284 LOG_SCOPE(
"solve()",
"NewtonSolver");
291 std::unique_ptr<NumericVector<Number>> linear_solution_ptr = newton_iterate.
zero_clone();
295 newton_iterate.
close();
296 linear_solution.
close();
299 #ifdef LIBMESH_ENABLE_CONSTRAINTS
329 <<
" with residual Not-a-Number"
331 libmesh_convergence_failure();
340 <<
" meets absolute tolerance "
349 if (current_residual == 0)
363 Real last_residual = current_residual;
375 << current_residual << std::endl;
378 current_linear_tolerance =
379 double(std::min (current_linear_tolerance,
389 current_linear_tolerance =
390 double(std::max(current_linear_tolerance,
399 linear_solution.
zero();
403 << current_linear_tolerance << std::endl;
406 const std::pair<unsigned int, Real> rval =
408 linear_solution, rhs, current_linear_tolerance,
416 if (linear_c_reason < 0)
421 libMesh::out <<
"Linear solver failed during Newton step, dropping out."
430 #ifdef LIBMESH_ENABLE_CONSTRAINTS
432 (
_system, &linear_solution,
true);
435 const unsigned int linear_steps = rval.first;
439 const bool linear_solve_finished =
443 libMesh::out <<
"Linear solve finished, step " << linear_steps
444 <<
", residual " << rval.second
453 newton_iterate.
add (-1., linear_solution);
454 newton_iterate.
close();
459 norm_total = newton_iterate.
l2_norm();
462 newton_iterate, norm_total,
478 current_residual = rhs.l2_norm();
481 << current_residual << std::endl;
485 linear_solve_finished &&
486 current_residual <= last_residual))
490 norm_delta, linear_solve_finished &&
491 current_residual <= last_residual);
500 last_residual, current_residual,
501 newton_iterate, linear_solution);
502 norm_delta *= steplength;
514 libMesh::out <<
" Nonlinear solver reached maximum step "
516 << current_residual << std::endl;
524 libmesh_convergence_failure();
530 norm_total = newton_iterate.
l2_norm();
538 << norm_delta / norm_total
539 <<
", |du| = " << norm_delta
545 linear_solve_finished))
549 norm_delta / steplength,
550 linear_solve_finished);
557 #ifdef LIBMESH_ENABLE_CONSTRAINTS
577 bool linear_solve_finished)
580 bool has_converged =
false;
586 has_converged =
true;
594 has_converged =
true;
598 if (!linear_solve_finished)
600 return has_converged;
607 has_converged =
true;
615 has_converged =
true;
618 return has_converged;
623 Real current_residual,
625 bool linear_solve_finished)
630 libMesh::out <<
" Nonlinear solver converged, step " << step_num
631 <<
", residual " << current_residual
638 << current_residual <<
" > "
646 libMesh::out <<
" Nonlinear solver converged, step " << step_num
647 <<
", residual reduction "
662 if (!linear_solve_finished)
668 libMesh::out <<
" Nonlinear solver converged, step " << step_num
669 <<
", absolute step size "
687 libMesh::out <<
" Nonlinear solver converged, step " << step_num
688 <<
", relative step size "
virtual void reinit()
The reinitialization function.
virtual void close()=0
Calls the SparseMatrix's internal assembly routines, ensuring that the values are consistent across p...
The DiffSolver achieved the desired absolute step size tolerance.
const SparseMatrix< Number > * request_matrix(const std::string &mat_name) const
virtual void zero()=0
Set all entries to zero.
virtual void add(const numeric_index_type i, const T value)=0
Adds value to each entry of the vector.
Manages consistently variables, degrees of freedom, coefficient vectors, and matrices for implicit sy...
NumericVector< Number > * rhs
The system matrix.
bool track_linear_convergence
If set to true, check for convergence of the linear solve.
bool require_residual_reduction
If this is set to true, the solver is forced to test the residual after each Newton step,...
virtual void init() override
The initialization function.
The DiffSolver achieved the desired relative step size tolerance.
The libMesh namespace provides an interface to certain functionality in the library.
bool continue_after_backtrack_failure
Defaults to false, telling the DiffSolver to throw an error when the backtracking scheme fails to fin...
virtual void close()=0
Calls the NumericVector's internal assembly routines, ensuring that the values are consistent across ...
Real absolute_step_tolerance
The DiffSolver should exit after the full nonlinear step norm is reduced to either less than absolute...
std::unique_ptr< LinearSolver< Number > > _linear_solver
The LinearSolver defines the interface used to solve the linear_implicit system.
MetaPhysicL::DualNumber< T, D > sqrt(const MetaPhysicL::DualNumber< T, D > &in)
static const Real TOLERANCE
The linear solver used by the DiffSolver failed to find a solution.
This is a generic class that defines a solver to handle ImplicitSystem classes, including NonlinearIm...
The DiffSolver failed to find a descent direction by backtracking (See newton_solver....
The DiffSolver achieved the desired relative residual tolerance.
unsigned int _solve_result
Initialized to zero.
double linear_tolerance_multiplier
The tolerance for linear solves is kept below this multiplier (which defaults to 1e-3) times the norm...
unsigned int _inner_iterations
The number of inner iterations used by the last solve.
virtual void init()
The initialization function.
Real line_search(Real tol, Real last_residual, Real ¤t_residual, NumericVector< Number > &newton_iterate, const NumericVector< Number > &linear_solution)
This does a line search in the direction opposite linear_solution to try and minimize the residual of...
LinearConvergenceReason
Linear solver convergence flags (taken from the PETSc flags).
MetaPhysicL::DualNumber< T, D > abs(const MetaPhysicL::DualNumber< T, D > &in)
double minimum_linear_tolerance
The tolerance for linear solves is kept above this minimum.
void print_convergence(unsigned int step_num, Real current_residual, Real step_norm, bool linear_solve_finished)
This prints output for the convergence criteria based on by the given residual and step size.
Real relative_step_tolerance
bool verbose
The DiffSolver may print a lot more to libMesh::out if verbose is set to true; default is false.
virtual void assembly(bool, bool, bool=false, bool=false)
Assembles a residual in rhs and/or a jacobian in matrix, as requested.
void enforce_constraints_exactly(const System &system, NumericVector< Number > *v=nullptr, bool homogeneous=false) const
Constrains the numeric vector v, which represents a solution defined on the mesh.
bool continue_after_max_iterations
Defaults to true, telling the DiffSolver to continue rather than exit when a solve has reached its ma...
SparseMatrix< Number > * matrix
The system matrix.
The DiffSolver achieved the desired absolute residual tolerance.
virtual void reinit() override
The reinitialization function.
The DiffSolver reached the maximum allowed number of nonlinear iterations before satisfying any conve...
bool quiet
The DiffSolver should not print anything to libMesh::out unless quiet is set to false; default is tru...
Real relative_residual_tolerance
std::unique_ptr< NumericVector< Number > > solution
Data structure to hold solution values.
std::unique_ptr< LinearSolutionMonitor > linear_solution_monitor
Pointer to functor which is called right after each linear solve.
unsigned int _outer_iterations
The number of outer iterations used by the last solve.
Real absolute_residual_tolerance
The DiffSolver should exit after the residual is reduced to either less than absolute_residual_tolera...
bool test_convergence(Real current_residual, Real step_norm, bool linear_solve_finished)
const std::string & name() const
This base class can be inherited from to provide interfaces to linear solvers from different packages...
unsigned int max_linear_iterations
Each linear solver step should exit after max_linear_iterations is exceeded.
virtual Real l2_norm() const =0
bool on_command_line(std::string arg)
virtual unsigned int solve() override
This method performs a solve, using an inexact Newton-Krylov method with line search.
const DofMap & get_dof_map() const
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
unsigned int max_nonlinear_iterations
The DiffSolver should exit in failure if max_nonlinear_iterations is exceeded and continue_after_max_...
NewtonSolver(sys_type &system)
Constructor.
Real max_solution_norm
The largest solution norm which the DiffSolver has yet seen will be stored here, to be used for stopp...
virtual ~NewtonSolver()
Destructor.
bool require_finite_residual
If this is set to true, the solver is forced to test the residual after each Newton step,...
Real minsteplength
If the quasi-Newton step length must be reduced to below this factor to give a residual reduction,...
virtual void update()
Update the local values to reflect the solution on neighboring processors.
virtual std::unique_ptr< NumericVector< T > > zero_clone() const =0
bool brent_line_search
If require_residual_reduction is true, the solver may reduce step lengths when required.
Real max_residual_norm
The largest nonlinear residual which the DiffSolver has yet seen will be stored here,...
sys_type & _system
A reference to the system we are solving.
A default or invalid solve result.
double initial_linear_tolerance
Any required linear solves will at first be done with this tolerance; the DiffSolver may tighten the ...