https://mooseframework.inl.gov
Loading...
Searching...
No Matches
MFEMNewtonNonlinearSolver.C
Go to the documentation of this file.
1//* This file is part of the MOOSE framework
2//* https://mooseframework.inl.gov
3//*
4//* All rights reserved, see COPYRIGHT for full restrictions
5//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6//*
7//* Licensed under LGPL 2.1, please see LICENSE for details
8//* https://www.gnu.org/licenses/lgpl-2.1.html
9
10#ifdef MOOSE_MFEM_ENABLED
11
13#include "MFEMProblem.h"
14
16
17namespace Moose::MFEM
18{
19void
20DampedNewtonSolver::SetOperator(const mfem::Operator & op)
21{
22 mfem::NewtonSolver::SetOperator(op);
23
24 _ls_x_trial.SetSize(width);
25 _ls_x_trial.UseDevice(true);
26
27 _ls_r_trial.SetSize(height);
28 _ls_r_trial.UseDevice(true);
29}
30
31void
33 mfem::real_t contraction_factor,
34 mfem::real_t sufficient_decrease)
35{
36 _ls_max_its = max_its;
37 _ls_contraction_factor = contraction_factor;
38 _ls_sufficient_decrease = sufficient_decrease;
39}
40
41mfem::real_t
42DampedNewtonSolver::ComputeScalingFactor(const mfem::Vector & x, const mfem::Vector & b) const
43{
44 if (_ls_max_its == 0)
45 return _damping_factor;
46
47 // NewtonSolver::Mult leaves the residual F(x) - b in r and the Newton update in c.
48 const auto have_b = (b.Size() == Height());
49 const auto norm = Norm(r);
50
52 for (const auto it : make_range(_ls_max_its))
53 {
54 add(x, -scale, c, _ls_x_trial);
55 oper->Mult(_ls_x_trial, _ls_r_trial);
56 if (have_b)
57 _ls_r_trial -= b;
58 const auto trial_norm = Norm(_ls_r_trial);
59
60 if (print_options.iterations)
61 mfem::out << "Newton line search iteration " << it << " : damping factor = " << scale
62 << ", ||r|| = " << trial_norm << '\n';
63
64 // Sufficient decrease (Armijo) condition on the residual norm, as used by the PETSc
65 // backtracking line search SNESLINESEARCHBT.
66 if (trial_norm <= (1.0 - _ls_sufficient_decrease * scale) * norm)
67 return scale;
68
70 }
71
72 if (print_options.warnings)
73 mfem::out << "Newton line search: no trial step satisfied the sufficient decrease "
74 "condition!\n";
75
76 // Interrupts the Newton iteration, which then reports no convergence.
77 return 0.0;
78}
79} // namespace Moose::MFEM
80
83{
85 params.addClassDescription("MFEM native nonlinear solver using Newton's method.");
86 MooseEnum line_search("none backtracking", "none");
87 params.addParam<MooseEnum>(
88 "line_search", line_search, "Line search used to shorten the Newton update.");
89 params.addRangeCheckedParam<mfem::real_t>(
90 "damping_factor",
91 1.0,
92 "damping_factor > 0 & damping_factor <= 1",
93 "Fraction of the full Newton update applied on each "
94 "nonlinear iteration, and the first trial step taken when "
95 "'line_search' is 'backtracking'.");
96 params.addRangeCheckedParam<unsigned int>(
97 "line_search_max_its",
98 10,
99 "line_search_max_its > 0",
100 "Maximum number of trial steps taken by the backtracking line search.");
101 params.addRangeCheckedParam<mfem::real_t>(
102 "line_search_contraction_factor",
103 0.5,
104 "line_search_contraction_factor > 0 & line_search_contraction_factor < 1",
105 "Factor a rejected backtracking trial step is multiplied by to obtain the next one.");
106 params.addRangeCheckedParam<mfem::real_t>(
107 "line_search_sufficient_decrease",
108 1.0e-4,
109 "line_search_sufficient_decrease >= 0 & line_search_sufficient_decrease < 1",
110 "Coefficient of the sufficient decrease condition the backtracking line search requires "
111 "of the residual norm.");
112 return params;
113}
114
116 : Moose::MFEM::NonlinearSolverBase(parameters)
117{
119}
120
121void
123{
124 auto solver = std::make_unique<Moose::MFEM::DampedNewtonSolver>(getMFEMProblem().getComm());
125 solver->iterative_mode = getParam<bool>("use_initial_guess");
126 solver->SetRelTol(getParam<mfem::real_t>("rel_tol"));
127 solver->SetAbsTol(getParam<mfem::real_t>("abs_tol"));
128 solver->SetMaxIter(getParam<unsigned int>("max_its"));
129 solver->SetPrintLevel(getParam<unsigned int>("print_level"));
130 solver->SetDampingFactor(getParam<mfem::real_t>("damping_factor"));
131
132 if (getParam<MooseEnum>("line_search") == "backtracking")
133 solver->SetBacktracking(getParam<unsigned int>("line_search_max_its"),
134 getParam<mfem::real_t>("line_search_contraction_factor"),
135 getParam<mfem::real_t>("line_search_sufficient_decrease"));
136 else
137 for (const auto & param : {"line_search_max_its",
138 "line_search_contraction_factor",
139 "line_search_sufficient_decrease"})
140 if (isParamSetByUser(param))
141 paramError(param, "Only used when 'line_search' is set to 'backtracking'.");
142
143 _solver = std::move(solver);
144}
145
146void
148{
149 cast_ref<mfem::NewtonSolver &>(GetSolver()).SetSolver(solver);
150}
151#endif
registerMooseObject("MooseApp", MFEMNewtonNonlinearSolver)
Real scale
Definition MortarUtils.C:62
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an optional parameter and a documentation string to the InputParameters object.
void addClassDescription(const std::string &doc_string)
This method adds a description of the class that will be displayed in the input file syntax dump.
void addRangeCheckedParam(const std::string &name, const T &value, const std::string &parsed_function, const std::string &doc_string)
MooseObject wrapper for mfem::NewtonSolver-backed nonlinear solves.
void ConstructSolver() override
Override in derived classes to construct and set the solver options.
void SetLinearSolver(mfem::Solver &solver) override
Configure the linear solver used inside the nonlinear solve.
MFEMNewtonNonlinearSolver(const InputParameters &parameters)
static InputParameters validParams()
MFEMProblem & getMFEMProblem()
Return the owning MFEM problem.
Definition MFEMObject.h:45
void paramError(const std::string &param, Args... args) const
Emits an error prefixed with the file and line number of the given param (from the input file) along ...
Definition MooseBase.h:457
bool isParamSetByUser(const std::string &name) const
Test if the supplied parameter is set by a user, as opposed to not set or set to default.
Definition MooseBase.h:205
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition MooseEnum.h:55
mfem::real_t ComputeScalingFactor(const mfem::Vector &x, const mfem::Vector &b) const override
Return the fraction of the Newton update to apply at the iterate x.
unsigned int _ls_max_its
Maximum number of trial steps taken by the line search; 0 disables backtracking.
mfem::Vector _ls_x_trial
Trial iterate x - t c evaluated by the line search.
void SetBacktracking(unsigned int max_its, mfem::real_t contraction_factor, mfem::real_t sufficient_decrease)
Enable a backtracking line search taking at most max_its trial steps, each a factor contraction_facto...
mfem::real_t _ls_sufficient_decrease
Coefficient of the sufficient decrease (Armijo) condition on the residual norm.
void SetOperator(const mfem::Operator &op) override
mfem::real_t _ls_contraction_factor
Factor a rejected trial step is multiplied by to obtain the next one.
mfem::real_t _damping_factor
Fraction of the full Newton update applied, and the line search's initial trial step.
mfem::Vector _ls_r_trial
Residual at the trial iterate.
mfem::Solver & GetSolver()
Returns the wrapped MFEM solver.
std::unique_ptr< mfem::Solver > _solver
Solver to be used for the problem.
Utilities for converting between vector(s) of libMesh Points and MFEM Vector(s).
MOOSE now contains C++17 code, so give a reasonable error message stating what the user can do to add...