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"    35   return b >= 0 ? std::abs(a) : -std::abs(a);
    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;
   134   const Real golden_ratio = 1.-(std::sqrt(5.)-1.)/2.;
   136   for (
unsigned int i=1; i <= max_i; i++)
   138       Real xm = (ax+cx)*0.5;
   139       Real tol1 = tol * std::abs(x) + tol*tol;
   140       Real tol2 = 2.0 * tol1;
   143       if (std::abs(x-xm) <= (tol2 - 0.5 * (cx - ax)))
   149       if (std::abs(e) > tol1)
   151           Real r = (x-w)*(fx-fv);
   152           Real q = (x-v)*(fx-fw);
   153           Real p = (x-v)*q-(x-w)*r;
   159           if (std::abs(p) >= std::abs(0.5*q*e) ||
   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;
   182       Real u = std::abs(d) >= tol1 ? x+d : x + 
SIGN(tol1,d);
   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),
   282   LOG_SCOPE(
"solve()", 
"NewtonSolver");
   289   std::unique_ptr<NumericVector<Number>> linear_solution_ptr = newton_iterate.
zero_clone();
   293   newton_iterate.
close();
   294   linear_solution.
close();
   297 #ifdef LIBMESH_ENABLE_CONSTRAINTS   328                        << 
" with residual Not-a-Number"   330           libmesh_convergence_failure();
   339                          << 
" meets absolute tolerance "   348           if (current_residual == 0)
   362       Real last_residual = current_residual;
   373                      << current_residual << std::endl;
   376       current_linear_tolerance =
   377         double(std::min (current_linear_tolerance,
   387       current_linear_tolerance =
   388         double(std::max(current_linear_tolerance,
   397       linear_solution.
zero();
   401                      << current_linear_tolerance << std::endl;
   404       const std::pair<unsigned int, Real> rval =
   406                                linear_solution, rhs, current_linear_tolerance,
   414           if (linear_c_reason < 0)
   419               libMesh::out << 
"Linear solver failed during Newton step, dropping out."   428 #ifdef LIBMESH_ENABLE_CONSTRAINTS   431           (
_system, &linear_solution,  
true);
   434       const unsigned int linear_steps = rval.first;
   438       const bool linear_solve_finished =
   442         libMesh::out << 
"Linear solve finished, step " << linear_steps
   443                      << 
", residual " << rval.second
   452       newton_iterate.
add (-1., linear_solution);
   453       newton_iterate.
close();
   458           norm_total = newton_iterate.
l2_norm();
   461                                            newton_iterate, norm_total,
   477           current_residual = rhs.l2_norm();
   480                          << current_residual << std::endl;
   484                                linear_solve_finished &&
   485                                current_residual <= last_residual))
   494                   norm_total = newton_iterate.
l2_norm();
   500                                   norm_delta, linear_solve_finished &&
   501                                   current_residual <= last_residual);
   510                           last_residual, current_residual,
   511                           newton_iterate, linear_solution);
   512       norm_delta *= steplength;
   524           libMesh::out << 
"  Nonlinear solver reached maximum step "   526                        << current_residual << std::endl;
   534               libmesh_convergence_failure();
   540       norm_total = newton_iterate.
l2_norm();
   548                      << norm_delta / norm_total
   549                      << 
", |du| = " << norm_delta
   555                            linear_solve_finished))
   559                               norm_delta / steplength,
   560                               linear_solve_finished);
   567 #ifdef LIBMESH_ENABLE_CONSTRAINTS   579                   !max_nonlinear_iterations);
   588                                     bool linear_solve_finished)
   591   bool has_converged = 
false;
   597       has_converged = 
true;
   605       has_converged = 
true;
   609   if (!linear_solve_finished)
   611       return has_converged;
   618       has_converged = 
true;
   627       has_converged = 
true;
   630   return has_converged;
   635                                      Real current_residual,
   637                                      bool linear_solve_finished)
   642       libMesh::out << 
"  Nonlinear solver converged, step " << step_num
   643                    << 
", residual " << current_residual
   650                      << current_residual << 
" > "   658       libMesh::out << 
"  Nonlinear solver converged, step " << step_num
   659                    << 
", residual reduction "   674   if (!linear_solve_finished)
   680       libMesh::out << 
"  Nonlinear solver converged, step " << step_num
   681                    << 
", absolute step size "   700       libMesh::out << 
"  Nonlinear solver converged, step " << step_num
   701                    << 
", relative step size " bool continue_after_max_iterations
Defaults to true, telling the DiffSolver to continue rather than exit when a solve has reached its ma...
virtual void init() override
The initialization function. 
NewtonSolver(sys_type &system)
Constructor. 
std::unique_ptr< LinearSolver< Number > > _linear_solver
The LinearSolver defines the interface used to solve the linear_implicit system. 
Real absolute_step_tolerance
The DiffSolver should exit after the full nonlinear step norm is reduced to either less than absolute...
bool quiet
The DiffSolver should not print anything to libMesh::out unless quiet is set to false; default is tru...
static constexpr Real TOLERANCE
virtual ~NewtonSolver()
Destructor. 
virtual std::unique_ptr< NumericVector< T > > zero_clone() const =0
unsigned int max_nonlinear_iterations
The DiffSolver should exit in failure if max_nonlinear_iterations is exceeded and continue_after_max_...
Real absolute_residual_tolerance
The DiffSolver should exit after the residual is reduced to either less than absolute_residual_tolera...
Real max_solution_norm
The largest solution norm which the DiffSolver has yet seen will be stored here, to be used for stopp...
Real max_residual_norm
The largest nonlinear residual which the DiffSolver has yet seen will be stored here, to be used for stopping criteria based on relative_residual_tolerance. 
bool _exact_constraint_enforcement
Whether we should enforce exact constraints globally during a solve. 
virtual unsigned int solve() override
This method performs a solve, using an inexact Newton-Krylov method with line search. 
The DiffSolver achieved the desired absolute step size tolerance. 
NumericVector< Number > * rhs
The system matrix. 
LinearConvergenceReason
Linear solver convergence flags (taken from the PETSc flags). 
virtual void reinit()
The reinitialization function. 
The libMesh namespace provides an interface to certain functionality in the library. 
The linear solver used by the DiffSolver failed to find a solution. 
const SparseMatrix< Number > * request_matrix(std::string_view mat_name) const
unsigned int _solve_result
Initialized to zero. 
unsigned int _inner_iterations
The number of inner iterations used by the last solve. 
double linear_tolerance_multiplier
The tolerance for linear solves is kept below this multiplier (which defaults to 1e-3) times the norm...
virtual void zero()=0
Set all entries to zero. 
virtual void init()
The initialization function. 
This is a generic class that defines a solver to handle ImplicitSystem classes, including NonlinearIm...
The DiffSolver reached the maximum allowed number of nonlinear iterations before satisfying any conve...
This base class can be inherited from to provide interfaces to linear solvers from different packages...
The DiffSolver achieved the desired relative step size tolerance. 
virtual void assembly(bool, bool, bool=false, bool=false)
Assembles a residual in rhs and/or a jacobian in matrix, as requested. 
sys_type & _system
A reference to the system we are solving. 
virtual Real l2_norm() const =0
unsigned int max_linear_iterations
Each linear solver step should exit after max_linear_iterations is exceeded. 
bool require_finite_residual
If this is set to true, the solver is forced to test the residual after each Newton step...
std::unique_ptr< NumericVector< Number > > solution
Data structure to hold solution values. 
The DiffSolver achieved the desired relative residual tolerance. 
bool track_linear_convergence
If set to true, check for convergence of the linear solve. 
virtual void close()=0
Calls the NumericVector's internal assembly routines, ensuring that the values are consistent across ...
double minimum_linear_tolerance
The tolerance for linear solves is kept above this minimum. 
bool verbose
The DiffSolver may print a lot more to libMesh::out if verbose is set to true; default is false...
virtual void update()
Update the local values to reflect the solution on neighboring processors. 
virtual void close()=0
Calls the SparseMatrix's internal assembly routines, ensuring that the values are consistent across p...
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
bool continue_after_backtrack_failure
Defaults to false, telling the DiffSolver to throw an error when the backtracking scheme fails to fin...
The DiffSolver achieved the desired absolute residual tolerance. 
Real minsteplength
If the quasi-Newton step length must be reduced to below this factor to give a residual reduction...
virtual void reinit() override
The reinitialization function. 
unsigned int _outer_iterations
The number of outer iterations used by the last solve. 
SparseMatrix< Number > * matrix
The system matrix. 
bool test_convergence(Real current_residual, Real step_norm, bool linear_solve_finished)
bool brent_line_search
If require_residual_reduction is true, the solver may reduce step lengths when required. 
The DiffSolver failed to find a descent direction by backtracking (See newton_solver.C) 
bool require_residual_reduction
If this is set to true, the solver is forced to test the residual after each Newton step...
bool on_command_line(std::string arg)
const std::string & name() const
A default or invalid solve result. 
virtual void add(const numeric_index_type i, const T value)=0
Adds value to the vector entry specified by i. 
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...
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...
double initial_linear_tolerance
Any required linear solves will at first be done with this tolerance; the DiffSolver may tighten the ...
const DofMap & get_dof_map() const
Real relative_residual_tolerance
Real relative_step_tolerance
std::unique_ptr< LinearSolutionMonitor > linear_solution_monitor
Pointer to functor which is called right after each linear solve. 
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. ...
Manages consistently variables, degrees of freedom, coefficient vectors, and matrices for implicit sy...