Nektar++
Loading...
Searching...
No Matches
NekNonlinSysIterNewtonBacktrack.cpp
Go to the documentation of this file.
1///////////////////////////////////////////////////////////////////////////////
2//
3// File: NekNonlinSysIterNewtonBacktrack.cpp
4//
5// For more information, please see: http://www.nektar.info
6//
7// The MIT License
8//
9// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10// Department of Aeronautics, Imperial College London (UK), and Scientific
11// Computing and Imaging Institute, University of Utah (USA).
12//
13// License for the specific language governing rights and limitations under
14// Permission is hereby granted, free of charge, to any person obtaining a
15// copy of this software and associated documentation files (the "Software"),
16// to deal in the Software without restriction, including without limitation
17// the rights to use, copy, modify, merge, publish, distribute, sublicense,
18// and/or sell copies of the Software, and to permit persons to whom the
19// Software is furnished to do so, subject to the following conditions:
20//
21// The above copyright notice and this permission notice shall be included
22// in all copies or substantial portions of the Software.
23//
24// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
25// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
30// DEALINGS IN THE SOFTWARE.
31//
32// Description: NekNonlinSysIterNewtonBacktrack definition
33//
34///////////////////////////////////////////////////////////////////////////////
35
37#include <algorithm>
38
39/* -- XML Parameter section --
40<SOLVERINFO>
41 <I PROPERTY="NonlinearSolver" VALUE="NewtonBacktrack" />
42</SOLVERINFO>
43
44<PARAMETERS>
45 <P> NewtonScaleInit = 1.0e-2 </P>
46 <P> NewtonScaleMax = 1.0e-1 </P>
47 <P> NewtonScaleMin = 1.0e-6 </P>
48 <P> NewtonScaleGrowFactor = 2.0 </P>
49 <P> BacktrackFactor = 0.5 </P>
50 <P> MaxBacktrackSteps = 4 </P>
51 <P> AcceptReductionEta = 1.0e-4 </P>
52</PARAMETERS>
53*/
54
55using namespace std;
56
58{
59
63 "Newton solver with residual-based backtracking.");
64
67 const LibUtilities::CommSharedPtr &vComm, const int nDimen,
68 const NekSysKey &pKey)
69 : NekNonlinSysIterNewton(pSession, vComm, nDimen, pKey)
70{
71 pSession->LoadParameter("NewtonScaleInit", m_newtonScaleInit, 1.0e-2);
72 pSession->LoadParameter("NewtonScaleMax", m_newtonScaleMax, 1.0e-1);
73 pSession->LoadParameter("NewtonScaleMin", m_newtonScaleMin, 1.0e-6);
74 pSession->LoadParameter("NewtonScaleGrowFactor", m_newtonScaleGrowFactor,
75 2.0);
76 pSession->LoadParameter("BacktrackFactor", m_backtrackFactor, 0.5);
77 pSession->LoadParameter("MaxBacktrackSteps", m_maxBacktrackSteps, 4);
78 pSession->LoadParameter("AcceptReductionEta", m_acceptReductionEta, 1.0e-4);
79}
80
82{
84
87
88 // In the backtracking solver, m_NewtonScale is the adaptive starting
89 // trial scale for the current Newton step.
91}
92
94 const int ntotal, const NekDouble oldResNorm)
95{
96 NekDouble alphaStart = std::min(m_NewtonScale, m_newtonScaleMax);
97 alphaStart = std::max(alphaStart, m_newtonScaleMin);
98
99 if (m_verbose)
100 {
101 cout << " Attempting to apply Newton update with NewtonBacktrack"
102 << endl;
103 }
104 NekDouble alpha = alphaStart;
105
106 for (int bt = 0; bt < m_maxBacktrackSteps; ++bt)
107 {
109 Vmath::Svtvp(ntotal, -alpha, m_DeltSltn, 1, m_solutionTrial, 1,
110 m_solutionTrial, 1);
111
113
114 NekDouble newResNormSq =
116 m_rowComm->AllReduce(newResNormSq, LibUtilities::ReduceSum);
117 NekDouble newResNorm = sqrt(newResNormSq);
118
119 if (m_verbose)
120 {
121 cout << "Bactracking trial " << bt + 1 << " of "
122 << m_maxBacktrackSteps + 1 << " with scale = " << alpha
123 << "\n new residual = " << newResNorm
124 << "\n old residual = " << oldResNorm
125 << "\n newResNorm / oldResNorm=" << newResNorm / oldResNorm
126 << endl;
127 }
128
129 if (newResNorm <= (1.0 - m_acceptReductionEta * alpha) * oldResNorm)
130 {
131 cout << "newResNorm <= (1.0 - m_acceptReductionEta * alpha) * "
132 "oldResNorm"
133 << endl;
134 cout << "newResNorm = " << newResNorm
135 << " m_acceptReductionEta = " << m_acceptReductionEta
136 << " alpha = " << alpha << endl;
140
141 if (bt == 0)
142 {
143 cout << "Good on the first try, grow alpha" << endl;
145 m_newtonScaleGrowFactor * alphaStart);
146 }
147 else
148 {
149 cout << "Good step, conserve alpha" << endl;
150 m_NewtonScale = alpha;
151 }
152
153 cout << " Accepted Newton scale = " << alpha
154 << " next starting scale = " << m_NewtonScale << endl;
155 return true;
156 }
157
158 alpha *= m_backtrackFactor;
159 if (alpha < m_newtonScaleMin)
160 {
161 break;
162 }
163 }
164
165 cout << "Fallback: take minimum allowed step and continue." << endl;
166 NekDouble alphaFallback = m_newtonScaleMin;
167
169 Vmath::Svtvp(ntotal, -alphaFallback, m_DeltSltn, 1, m_solutionTrial, 1,
170 m_solutionTrial, 1);
171
173
174 NekDouble fallbackResNormSq =
176 m_rowComm->AllReduce(fallbackResNormSq, LibUtilities::ReduceSum);
177 NekDouble fallbackResNorm = sqrt(fallbackResNormSq);
178
179 cout << " No acceptable backtracking step found."
180 << " Taking fallback Newton scale = " << alphaFallback
181 << "\n new residual = " << fallbackResNorm
182 << "\n old residual = " << oldResNorm << endl;
183 cout << "newResNorm / oldResNorm=" << fallbackResNorm / oldResNorm << endl;
184
188
189 // Keep next iteration conservative.
191
192 return true;
193}
194
195} // namespace Nektar::LibUtilities
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
NekNonlinSysIterNewtonBacktrack(const LibUtilities::SessionReaderSharedPtr &pSession, const LibUtilities::CommSharedPtr &vComm, const int nDimen, const NekSysKey &pKey)
bool v_ApplyNewtonUpdate(const int ntotal, const NekDouble oldResNorm) override
static NekNonlinSysIterSharedPtr create(const LibUtilities::SessionReaderSharedPtr &pSession, const LibUtilities::CommSharedPtr &vComm, const int nDimen, const NekSysKey &pKey)
LibUtilities::CommSharedPtr m_rowComm
Definition NekSys.h:299
NekSysOperators m_operator
Definition NekSys.h:306
void DoNekSysResEval(InArrayType &inarray, OutArrayType &outarray, const bool &flag=false) const
Definition NekSys.h:141
NekNonlinSysIterFactory & GetNekNonlinSysIterFactory()
std::shared_ptr< SessionReader > SessionReaderSharedPtr
std::shared_ptr< Comm > CommSharedPtr
Pointer to a Communicator object.
Definition Comm.h:55
void Svtvp(int n, const T alpha, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Svtvp (scalar times vector plus vector): z = alpha*x + y.
Definition Vmath.hpp:396
T Dot(int n, const T *w, const T *x)
dot product
Definition Vmath.hpp:761
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition Vmath.hpp:825
STL namespace.
scalarT< T > sqrt(scalarT< T > in)
Definition scalar.hpp:290