libMesh
Loading...
Searching...
No Matches
newton_solver.C
Go to the documentation of this file.
1// The libMesh Finite Element Library.
2// Copyright (C) 2002-2026 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3
4// This library is free software; you can redistribute it and/or
5// modify it under the terms of the GNU Lesser General Public
6// License as published by the Free Software Foundation; either
7// version 2.1 of the License, or (at your option) any later version.
8
9// This library is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12// Lesser General Public License for more details.
13
14// You should have received a copy of the GNU Lesser General Public
15// License along with this library; if not, write to the Free Software
16// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
18
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"
26
27namespace libMesh
28{
29
30// SIGN from Numerical Recipes
31template <typename T>
32inline
33T SIGN(T a, T b)
34{
35 return b >= 0 ? std::abs(a) : -std::abs(a);
36}
37
39 Real last_residual,
40 Real & current_residual,
41 NumericVector<Number> & newton_iterate,
42 const NumericVector<Number> & linear_solution)
43{
44 // Take a full step if we got a residual reduction or if we
45 // aren't substepping
46 if ((current_residual < last_residual) ||
48 (!require_finite_residual || !libmesh_isnan(current_residual))))
49 return 1.;
50
51 // The residual vector
53
54 Real ax = 0.; // First abscissa, don't take negative steps
55 Real cx = 1.; // Second abscissa, don't extrapolate steps
56
57 // Find bx, a step length that gives lower residual than ax or cx
58 Real bx = 1.;
59
60 while (libmesh_isnan(current_residual) ||
61 (current_residual > last_residual &&
63 {
64 // Reduce step size to 1/2, 1/4, etc.
65 Real substepdivision;
66 if (brent_line_search && !libmesh_isnan(current_residual))
67 {
68 substepdivision = std::min(0.5, last_residual/current_residual);
69 substepdivision = std::max(substepdivision, tol*2.);
70 }
71 else
72 substepdivision = 0.5;
73
74 newton_iterate.add (bx * (1.-substepdivision),
75 linear_solution);
76 newton_iterate.close();
77 bx *= substepdivision;
78 if (verbose)
79 libMesh::out << " Shrinking Newton step to "
80 << bx << std::endl;
81
82 // We may need to localize a parallel solution
84
85 // Check residual with fractional Newton step
87
88 rhs.close();
89 current_residual = rhs.l2_norm();
90 if (verbose)
91 libMesh::out << " Current Residual: "
92 << current_residual << std::endl;
93
94 if (bx/2. < minsteplength &&
95 (libmesh_isnan(current_residual) ||
96 (current_residual > last_residual)))
97 {
98 libMesh::out << "Inexact Newton step FAILED at step "
99 << _outer_iterations << std::endl;
100
102 {
103 libmesh_convergence_failure();
104 }
105 else
106 {
107 libMesh::out << "Continuing anyway ..." << std::endl;
109 return bx;
110 }
111 }
112 } // end while (current_residual > last_residual)
113
114 // Now return that reduced-residual step, or use Brent's method to
115 // find a more optimal step.
116
118 return bx;
119
120 // Brent's method adapted from Numerical Recipes in C, ch. 10.2
121 Real e = 0.;
122
123 Real x = bx, w = bx, v = bx;
124
125 // Residuals at bx
126 Real fx = current_residual,
127 fw = current_residual,
128 fv = current_residual;
129
130 // Max iterations for Brent's method loop
131 const unsigned int max_i = 20;
132
133 // for golden ratio steps
134 const Real golden_ratio = 1.-(std::sqrt(5.)-1.)/2.;
135
136 for (unsigned int i=1; i <= max_i; i++)
137 {
138 Real xm = (ax+cx)*0.5;
139 Real tol1 = tol * std::abs(x) + tol*tol;
140 Real tol2 = 2.0 * tol1;
141
142 // Test if we're done
143 if (std::abs(x-xm) <= (tol2 - 0.5 * (cx - ax)))
144 return x;
145
146 Real d;
147
148 // Construct a parabolic fit
149 if (std::abs(e) > tol1)
150 {
151 Real r = (x-w)*(fx-fv);
152 Real q = (x-v)*(fx-fw);
153 Real p = (x-v)*q-(x-w)*r;
154 q = 2. * (q-r);
155 if (q > 0.)
156 p = -p;
157 else
158 q = std::abs(q);
159 if (std::abs(p) >= std::abs(0.5*q*e) ||
160 p <= q * (ax-x) ||
161 p >= q * (cx-x))
162 {
163 // Take a golden section step
164 e = x >= xm ? ax-x : cx-x;
165 d = golden_ratio * e;
166 }
167 else
168 {
169 // Take a parabolic fit step
170 d = p/q;
171 if (x+d-ax < tol2 || cx-(x+d) < tol2)
172 d = SIGN(tol1, xm - x);
173 }
174 }
175 else
176 {
177 // Take a golden section step
178 e = x >= xm ? ax-x : cx-x;
179 d = golden_ratio * e;
180 }
181
182 Real u = std::abs(d) >= tol1 ? x+d : x + SIGN(tol1,d);
183
184 // Assemble the residual at the new steplength u
185 newton_iterate.add (bx - u, linear_solution);
186 newton_iterate.close();
187 bx = u;
188 if (verbose)
189 libMesh::out << " Shrinking Newton step to "
190 << bx << std::endl;
191
192 // We may need to localize a parallel solution
193 _system.update();
195
196 rhs.close();
197 Real fu = current_residual = rhs.l2_norm();
198 if (verbose)
199 libMesh::out << " Current Residual: "
200 << fu << std::endl;
201
202 if (fu <= fx)
203 {
204 if (u >= x)
205 ax = x;
206 else
207 cx = x;
208 v = w; w = x; x = u;
209 fv = fw; fw = fx; fx = fu;
210 }
211 else
212 {
213 if (u < x)
214 ax = u;
215 else
216 cx = u;
217 if (fu <= fw || w == x)
218 {
219 v = w; w = u;
220 fv = fw; fw = fu;
221 }
222 else if (fu <= fv || v == x || v == w)
223 {
224 v = u;
225 fv = fu;
226 }
227 }
228 }
229
230 if (!quiet)
231 libMesh::out << "Warning! Too many iterations used in Brent line search!"
232 << std::endl;
233 return bx;
234}
235
236
238 : Parent(s),
239 require_residual_reduction(true),
240 require_finite_residual(true),
241 brent_line_search(true),
242 track_linear_convergence(false),
243 minsteplength(1e-5),
244 linear_tolerance_multiplier(1e-3),
245 _linear_solver(LinearSolver<Number>::build(s.comm()))
246{
247}
248
249
250
251NewtonSolver::~NewtonSolver () = default;
252
253
254
256{
257 Parent::init();
258
259 if (libMesh::on_command_line("--solver-system-names"))
260 _linear_solver->init((_system.name()+"_").c_str());
261 else
262 _linear_solver->init();
263
264 _linear_solver->init_systems(_system);
265}
266
267
268
270{
272
273 _linear_solver->clear();
274
275 _linear_solver->init_systems(_system);
276}
277
278
279
281{
282 LOG_SCOPE("solve()", "NewtonSolver");
283
284 // Reset any prior solve result
286
287 NumericVector<Number> & newton_iterate = *(_system.solution);
288
289 std::unique_ptr<NumericVector<Number>> linear_solution_ptr = newton_iterate.zero_clone();
290 NumericVector<Number> & linear_solution = *linear_solution_ptr;
292
293 newton_iterate.close();
294 linear_solution.close();
295 rhs.close();
296
297#ifdef LIBMESH_ENABLE_CONSTRAINTS
300#endif
301
302 SparseMatrix<Number> & matrix = *(_system.matrix);
303
304 // Set starting linear tolerance
305 double current_linear_tolerance = initial_linear_tolerance;
306
307 // Start counting our linear solver steps
309
310 // Now we begin the nonlinear loop
313 {
314 // We may need to localize a parallel solution
315 _system.update();
316
317 if (verbose)
318 libMesh::out << "Assembling the System" << std::endl;
319
321 rhs.close();
322 Real current_residual = rhs.l2_norm();
323
324 if (libmesh_isnan(current_residual))
325 {
326 libMesh::out << " Nonlinear solver DIVERGED at step "
328 << " with residual Not-a-Number"
329 << std::endl;
330 libmesh_convergence_failure();
331 continue;
332 }
333
334 if (current_residual <= absolute_residual_tolerance)
335 {
336 if (verbose)
337 libMesh::out << "Linear solve unnecessary; residual "
338 << current_residual
339 << " meets absolute tolerance "
341 << std::endl;
342
343 // We're not doing a solve, but other code may reuse this
344 // matrix.
345 matrix.close();
346
348 if (current_residual == 0)
349 {
356 }
357
358 break;
359 }
360
361 // Prepare to take incomplete steps
362 Real last_residual = current_residual;
363
364 max_residual_norm = std::max (current_residual,
366
367 // Compute the l2 norm of the whole solution
368 Real norm_total = newton_iterate.l2_norm();
369 max_solution_norm = std::max(max_solution_norm, norm_total);
370
371 if (verbose)
372 libMesh::out << "Nonlinear Residual: "
373 << current_residual << std::endl;
374
375 // Make sure our linear tolerance is low enough
376 current_linear_tolerance =
377 double(std::min (current_linear_tolerance,
378 current_residual * linear_tolerance_multiplier));
379
380 // But don't let it be too small
381 if (current_linear_tolerance < minimum_linear_tolerance)
382 {
383 current_linear_tolerance = minimum_linear_tolerance;
384 }
385
386 // If starting the nonlinear solve with a really good initial guess, we dont want to set an absurd linear tolerance
387 current_linear_tolerance =
388 double(std::max(current_linear_tolerance,
389 absolute_residual_tolerance / current_residual
390 / 10.0));
391
392 // At this point newton_iterate is the current guess, and
393 // linear_solution is now about to become the NEGATIVE of the next
394 // Newton step.
395
396 // Our best initial guess for the linear_solution is zero!
397 linear_solution.zero();
398
399 if (verbose)
400 libMesh::out << "Linear solve starting, tolerance "
401 << current_linear_tolerance << std::endl;
402
403 // Solve the linear system.
404 const std::pair<unsigned int, Real> rval =
405 _linear_solver->solve (matrix, _system.request_matrix("Preconditioner"),
406 linear_solution, rhs, current_linear_tolerance,
408
410 {
411 LinearConvergenceReason linear_c_reason = _linear_solver->get_converged_reason();
412
413 // Check if something went wrong during the linear solve
414 if (linear_c_reason < 0)
415 {
416 // The linear solver failed somehow
418 // Print a message
419 libMesh::out << "Linear solver failed during Newton step, dropping out."
420 << std::endl;
421 break;
422 }
423 }
424
425 // We may need to localize a parallel solution
426 _system.update ();
427 // The linear solver may not have fit our constraints exactly
428#ifdef LIBMESH_ENABLE_CONSTRAINTS
431 (_system, &linear_solution, /* homogeneous = */ true);
432#endif
433
434 const unsigned int linear_steps = rval.first;
435 libmesh_assert_less_equal (linear_steps, max_linear_iterations);
436 _inner_iterations += linear_steps;
437
438 const bool linear_solve_finished =
439 !(linear_steps == max_linear_iterations);
440
441 if (verbose)
442 libMesh::out << "Linear solve finished, step " << linear_steps
443 << ", residual " << rval.second
444 << std::endl;
445
446 // Compute the l2 norm of the nonlinear update
447 Real norm_delta = linear_solution.l2_norm();
448
449 if (verbose)
450 libMesh::out << "Trying full Newton step" << std::endl;
451 // Take a full Newton step
452 newton_iterate.add (-1., linear_solution);
453 newton_iterate.close();
454
455 if (this->linear_solution_monitor.get())
456 {
457 // Compute the l2 norm of the whole solution
458 norm_total = newton_iterate.l2_norm();
459 rhs.close();
460 (*this->linear_solution_monitor)(linear_solution, norm_delta,
461 newton_iterate, norm_total,
462 rhs, rhs.l2_norm(), _outer_iterations);
463 }
464
465 // Check residual with full Newton step, if that's useful for determining
466 // whether to line search, whether to quit early, or whether to die after
467 // hitting our max iteration count
468 if (this->require_residual_reduction ||
470 _outer_iterations+1 < max_nonlinear_iterations ||
472 {
473 _system.update ();
475
476 rhs.close();
477 current_residual = rhs.l2_norm();
478 if (verbose)
479 libMesh::out << " Current Residual: "
480 << current_residual << std::endl;
481
482 // don't fiddle around if we've already converged
483 if (test_convergence(current_residual, norm_delta,
484 linear_solve_finished &&
485 current_residual <= last_residual))
486 {
487 // Make sure we have an up to date max_solution_norm if
488 // we're going to be verbose about it here. We don't
489 // want to update it earlier because we don't want an
490 // excessive full Newton step to explode it if we're
491 // just going to line search that step back.
492 if (!quiet && verbose)
493 {
494 norm_total = newton_iterate.l2_norm();
495 max_solution_norm = std::max(max_solution_norm, norm_total);
496 }
497
498 if (!quiet)
499 print_convergence(_outer_iterations, current_residual,
500 norm_delta, linear_solve_finished &&
501 current_residual <= last_residual);
503 break; // out of _outer_iterations for loop
504 }
505 }
506
507 // since we're not converged, backtrack if necessary
508 Real steplength =
509 this->line_search(std::sqrt(TOLERANCE),
510 last_residual, current_residual,
511 newton_iterate, linear_solution);
512 norm_delta *= steplength;
513
514 // Check to see if backtracking failed,
515 // and break out of the nonlinear loop if so...
517 {
519 break; // out of _outer_iterations for loop
520 }
521
523 {
524 libMesh::out << " Nonlinear solver reached maximum step "
525 << max_nonlinear_iterations << ", latest evaluated residual "
526 << current_residual << std::endl;
528 {
530 libMesh::out << " Continuing..." << std::endl;
531 }
532 else
533 {
534 libmesh_convergence_failure();
535 }
536 continue;
537 }
538
539 // Compute the l2 norm of the whole solution
540 norm_total = newton_iterate.l2_norm();
541
542 max_solution_norm = std::max(max_solution_norm, norm_total);
543
544 // Print out information for the
545 // nonlinear iterations.
546 if (verbose)
547 libMesh::out << " Nonlinear step: |du|/|u| = "
548 << norm_delta / norm_total
549 << ", |du| = " << norm_delta
550 << std::endl;
551
552 // Terminate the solution iteration if the difference between
553 // this iteration and the last is sufficiently small.
554 if (test_convergence(current_residual, norm_delta / steplength,
555 linear_solve_finished))
556 {
557 if (!quiet)
558 print_convergence(_outer_iterations, current_residual,
559 norm_delta / steplength,
560 linear_solve_finished);
562 break; // out of _outer_iterations for loop
563 }
564 } // end nonlinear loop
565
566 // The linear solver may not have fit our constraints exactly
567#ifdef LIBMESH_ENABLE_CONSTRAINTS
570#endif
571
572 // We may need to localize a parallel solution
573 _system.update ();
574
575 // Make sure we are returning something sensible as the
576 // _solve_result, except in the edge case where we weren't really asked to
577 // solve.
579 !max_nonlinear_iterations);
580
581 return _solve_result;
582}
583
584
585
587 Real step_norm,
588 bool linear_solve_finished)
589{
590 // We haven't converged unless we pass a convergence test
591 bool has_converged = false;
592
593 // Is our absolute residual low enough?
594 if (current_residual < absolute_residual_tolerance)
595 {
597 has_converged = true;
598 }
599
600 // Is our relative residual low enough?
601 if ((current_residual / max_residual_norm) <
603 {
605 has_converged = true;
606 }
607
608 // For incomplete linear solves, it's not safe to test step sizes
609 if (!linear_solve_finished)
610 {
611 return has_converged;
612 }
613
614 // Is our absolute Newton step size small enough?
615 if (step_norm < absolute_step_tolerance)
616 {
618 has_converged = true;
619 }
620
621 // Is our relative Newton step size small enough?
622 if (max_solution_norm &&
623 (step_norm / max_solution_norm <
625 {
627 has_converged = true;
628 }
629
630 return has_converged;
631}
632
633
634void NewtonSolver::print_convergence(unsigned int step_num,
635 Real current_residual,
636 Real step_norm,
637 bool linear_solve_finished)
638{
639 // Is our absolute residual low enough?
640 if (current_residual < absolute_residual_tolerance)
641 {
642 libMesh::out << " Nonlinear solver converged, step " << step_num
643 << ", residual " << current_residual
644 << std::endl;
645 }
647 {
648 if (verbose)
649 libMesh::out << " Nonlinear solver current_residual "
650 << current_residual << " > "
651 << (absolute_residual_tolerance) << std::endl;
652 }
653
654 // Is our relative residual low enough?
655 if ((current_residual / max_residual_norm) <
657 {
658 libMesh::out << " Nonlinear solver converged, step " << step_num
659 << ", residual reduction "
660 << current_residual / max_residual_norm
662 << std::endl;
663 }
665 {
666 if (verbose)
667 libMesh::out << " Nonlinear solver relative residual "
668 << (current_residual / max_residual_norm)
670 << std::endl;
671 }
672
673 // For incomplete linear solves, it's not safe to test step sizes
674 if (!linear_solve_finished)
675 return;
676
677 // Is our absolute Newton step size small enough?
678 if (step_norm < absolute_step_tolerance)
679 {
680 libMesh::out << " Nonlinear solver converged, step " << step_num
681 << ", absolute step size "
682 << step_norm
683 << " < " << absolute_step_tolerance
684 << std::endl;
685 }
687 {
688 if (verbose)
689 libMesh::out << " Nonlinear solver absolute step size "
690 << step_norm
691 << " > " << absolute_step_tolerance
692 << std::endl;
693 }
694
695 // Is our relative Newton step size small enough?
696 if (max_solution_norm &&
697 (step_norm / max_solution_norm <
699 {
700 libMesh::out << " Nonlinear solver converged, step " << step_num
701 << ", relative step size "
702 << (step_norm / max_solution_norm)
703 << " < " << relative_step_tolerance
704 << std::endl;
705 }
707 {
708 if (verbose)
709 {
711 libMesh::out << " Nonlinear solver relative step size "
712 << (step_norm / max_solution_norm)
713 << " > " << relative_step_tolerance
714 << std::endl;
715 }
716 }
717}
718
719} // namespace libMesh
This is a generic class that defines a solver to handle ImplicitSystem classes, including NonlinearIm...
Definition diff_solver.h:70
unsigned int _inner_iterations
The number of inner 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...
Real absolute_step_tolerance
The DiffSolver should exit after the full nonlinear step norm is reduced to either less than absolute...
std::unique_ptr< LinearSolutionMonitor > linear_solution_monitor
Pointer to functor which is called right after each linear solve.
unsigned int max_linear_iterations
Each linear solver step should exit after max_linear_iterations is exceeded.
double minimum_linear_tolerance
The tolerance for linear solves is kept above this minimum.
bool continue_after_backtrack_failure
Defaults to false, telling the DiffSolver to throw an error when the backtracking scheme fails to fin...
Real max_residual_norm
The largest nonlinear residual which the DiffSolver has yet seen will be stored here,...
Real max_solution_norm
The largest solution norm which the DiffSolver has yet seen will be stored here, to be used for stopp...
virtual void init()
The initialization function.
Definition diff_solver.C:72
sys_type & _system
A reference to the system we are solving.
bool continue_after_max_iterations
Defaults to true, telling the DiffSolver to continue rather than exit when a solve has reached its ma...
@ DIVERGED_BACKTRACKING_FAILURE
The DiffSolver failed to find a descent direction by backtracking (See newton_solver....
@ DIVERGED_MAX_NONLINEAR_ITERATIONS
The DiffSolver reached the maximum allowed number of nonlinear iterations before satisfying any conve...
@ CONVERGED_RELATIVE_STEP
The DiffSolver achieved the desired relative step size tolerance.
@ CONVERGED_ABSOLUTE_RESIDUAL
The DiffSolver achieved the desired absolute residual tolerance.
@ DIVERGED_LINEAR_SOLVER_FAILURE
The linear solver used by the DiffSolver failed to find a solution.
@ INVALID_SOLVE_RESULT
A default or invalid solve result.
@ CONVERGED_RELATIVE_RESIDUAL
The DiffSolver achieved the desired relative residual tolerance.
@ CONVERGED_ABSOLUTE_STEP
The DiffSolver achieved the desired absolute step size tolerance.
double initial_linear_tolerance
Any required linear solves will at first be done with this tolerance; the DiffSolver may tighten the ...
unsigned int _outer_iterations
The number of outer iterations used by the last solve.
virtual void reinit()
The reinitialization function.
Definition diff_solver.C:63
bool _exact_constraint_enforcement
Whether we should enforce exact constraints globally during a solve.
unsigned int _solve_result
Initialized to zero.
bool verbose
The DiffSolver may print a lot more to libMesh::out if verbose is set to true; default is false.
unsigned int max_nonlinear_iterations
The DiffSolver should exit in failure if max_nonlinear_iterations is exceeded and continue_after_max_...
bool quiet
The DiffSolver should not print anything to libMesh::out unless quiet is set to false; default is tru...
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.
Definition dof_map.h:2518
NumericVector< Number > * rhs
The system matrix.
Manages consistently variables, degrees of freedom, coefficient vectors, and matrices for implicit sy...
SparseMatrix< Number > * matrix
The system matrix.
virtual void assembly(bool, bool, bool=false, bool=false)
Assembles a residual in rhs and/or a jacobian in matrix, as requested.
This base class can be inherited from to provide interfaces to linear solvers from different packages...
bool require_residual_reduction
If this is set to true, the solver is forced to test the residual after each Newton step,...
double linear_tolerance_multiplier
The tolerance for linear solves is kept below this multiplier (which defaults to 1e-3) times the norm...
bool test_convergence(Real current_residual, Real step_norm, bool linear_solve_finished)
virtual void reinit() override
The reinitialization function.
bool require_finite_residual
If this is set to true, the solver is forced to test the residual after each Newton step,...
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 minsteplength
If the quasi-Newton step length must be reduced to below this factor to give a residual reduction,...
NewtonSolver(sys_type &system)
Constructor.
bool track_linear_convergence
If set to true, check for convergence of the linear solve.
virtual void init() override
The initialization function.
Real line_search(Real tol, Real last_residual, Real &current_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...
virtual ~NewtonSolver()
Destructor.
bool brent_line_search
If require_residual_reduction is true, the solver may reduce step lengths when required.
virtual unsigned int solve() override
This method performs a solve, using an inexact Newton-Krylov method with line search.
std::unique_ptr< LinearSolver< Number > > _linear_solver
The LinearSolver defines the interface used to solve the linear_implicit system.
Provides a uniform interface to vector storage schemes for different linear algebra libraries.
virtual void close()=0
Calls the NumericVector's internal assembly routines, ensuring that the values are consistent across ...
virtual Real l2_norm() const =0
virtual void zero()=0
Set all entries to zero.
virtual std::unique_ptr< NumericVector< T > > zero_clone() const =0
virtual void add(const numeric_index_type i, const T value)=0
Adds value to the vector entry specified by i.
Generic sparse matrix.
virtual void close()=0
Calls the SparseMatrix's internal assembly routines, ensuring that the values are consistent across p...
const std::string & name() const
Definition system.h:2385
std::unique_ptr< NumericVector< Number > > solution
Data structure to hold solution values.
Definition system.h:1655
virtual void update()
Update the local values to reflect the solution on neighboring processors.
Definition system.C:498
const DofMap & get_dof_map() const
Definition system.h:2417
const SparseMatrix< Number > * request_matrix(std::string_view mat_name) const
Definition system.C:1087
static const Real b
The libMesh namespace provides an interface to certain functionality in the library.
libmesh_assert(ctx)
OStreamProxy out
static constexpr Real TOLERANCE
T SIGN(T a, T b)
bool libmesh_isnan(T x)
bool on_command_line(std::string arg)
Definition libmesh.C:934
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
LinearConvergenceReason
Linear solver convergence flags (taken from the PETSc flags).