Nektar++
NekNonlinSysNewton.cpp
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // File: NekNonlinSysNewton.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: NekNonlinSysNewton definition
33 //
34 ///////////////////////////////////////////////////////////////////////////////
35 
38 
39 using namespace std;
40 
41 namespace Nektar
42 {
43 namespace LibUtilities
44 {
45 /**
46  * @class NekNonlinSysNewton
47  *
48  * Solves a nonlinear system using iterative methods.
49  */
50 string NekNonlinSysNewton::className =
52  "Newton", NekNonlinSysNewton::create, "NekNonlinSysNewton solver.");
53 
54 NekNonlinSysNewton::NekNonlinSysNewton(
56  const LibUtilities::CommSharedPtr &vComm, const int nscale,
57  const NekSysKey &pKey)
58  : NekNonlinSys(pSession, vComm, nscale, pKey)
59 {
60 }
61 
63 {
68 }
69 
71 {
72 }
73 
74 /**
75  *
76  **/
78  const int nGlobal, const Array<OneD, const NekDouble> &pInput,
79  Array<OneD, NekDouble> &pOutput, const int nDir, const NekDouble tol,
80  const NekDouble factor)
81 {
82  boost::ignore_unused(factor);
83 
84  int nwidthcolm = 11;
85 
86  v_SetupNekNonlinSystem(nGlobal, pInput, pInput, nDir);
87 
88  m_Solution = pOutput;
89  Vmath::Vcopy(nGlobal - nDir, pInput, 1, m_Solution, 1);
90 
91  int ntotal = nGlobal - nDir;
92  m_NtotLinSysIts = 0;
93 
94  int NttlNonlinIte = 0;
95  m_converged = false;
96 
97  NekDouble resnormOld = 0.0;
98  for (int k = 0; k < m_maxiter; ++k)
99  {
101  if (m_converged)
102  break;
103 
104  NekDouble LinSysRelativeIteTol;
105  CalcInexactNewtonForcing(k, resnormOld, m_SysResNorm,
106  LinSysRelativeIteTol);
107 
108  resnormOld = m_SysResNorm;
109 
110  NekDouble LinSysTol = LinSysRelativeIteTol * sqrt(m_SysResNorm);
111  int ntmpLinSysIts =
112  m_linsol->SolveSystem(ntotal, m_Residual, m_DeltSltn, 0, LinSysTol);
113  m_NtotLinSysIts += ntmpLinSysIts;
114  Vmath::Vsub(ntotal, m_Solution, 1, m_DeltSltn, 1, m_Solution, 1);
115  NttlNonlinIte++;
117  }
118 
119  if (((!m_converged) || m_verbose) && m_root && m_FlagWarnings)
120  {
122  " # Nonlinear solver not converge in DoImplicitSolve");
123  cout << right << scientific << setw(nwidthcolm)
124  << setprecision(nwidthcolm - 6)
125  << " * Newton-Its converged (RES=" << sqrt(m_SysResNorm)
126  << " Res/(DtRHS): " << sqrt(m_SysResNorm / m_SysResNorm0)
127  << " with " << setw(3) << NttlNonlinIte << " Non-Its)" << endl;
128  }
129 
130  m_ResidualUpdated = false;
131  return NttlNonlinIte;
132 }
133 
135  const int nIteration, const Array<OneD, const NekDouble> &Residual,
136  const NekDouble tol)
137 {
138  bool converged = false;
139  NekDouble resratio = 1.0;
140  int ntotal = Residual.size();
141 
142  m_SysResNorm = Vmath::Dot(ntotal, Residual, Residual);
144 
145  if (0 == nIteration)
146  {
148  resratio = 1.0;
149  }
150  else
151  {
152  resratio = m_SysResNorm / m_SysResNorm0;
153  }
154 
156  m_SysResNorm < tol)
157  {
158  converged = true;
159  }
160 
161  return converged;
162 }
163 
165  NekDouble &resnormOld,
166  const NekDouble &resnorm,
167  NekDouble &forcing)
168 {
169  if (0 == k)
170  {
171  forcing = m_LinSysRelativeTolInNonlin;
172  resnormOld = resnorm;
173  }
174  else
175  {
176  switch (m_InexactNewtonForcing)
177  {
178  case 0:
179  {
180  forcing = m_LinSysRelativeTolInNonlin;
181  break;
182  }
183  case 1:
184  {
185  NekDouble tmpForc = m_forcingGamma *
186  pow((resnorm / resnormOld), m_forcingAlpha);
187  NekDouble tmp = m_forcingGamma * pow(forcing, m_forcingAlpha);
188  if (tmp > 0.1)
189  {
190  forcing =
191  min(m_LinSysRelativeTolInNonlin, max(tmp, tmpForc));
192  }
193  else
194  {
195  forcing = min(m_LinSysRelativeTolInNonlin, tmpForc);
196  }
197 
198  forcing = max(forcing, 1.0E-6);
199  break;
200  }
201  }
202  }
203 }
204 
206  const int nGlobal, const Array<OneD, const NekDouble> &pInput,
207  const Array<OneD, const NekDouble> &pSource, const int nDir)
208 {
209  boost::ignore_unused(nGlobal, nDir);
210 
211  ASSERTL0(0 == nDir, "0 != nDir not tested");
212  ASSERTL0(m_SysDimen == nGlobal, "m_SysDimen!=nGlobal");
213 
214  m_SourceVec = pSource;
215  Vmath::Vcopy(nGlobal - nDir, pSource, 1, m_SourceVec, 1);
216 
217  if (!m_ResidualUpdated)
218  {
220  m_ResidualUpdated = true;
221  }
222  m_linsol->SetSysOperators(m_operator);
223 }
224 
225 } // namespace LibUtilities
226 } // namespace Nektar
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:215
#define WARNINGL0(condition, msg)
Definition: ErrorUtil.hpp:222
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
Definition: NekFactory.hpp:198
Array< OneD, NekDouble > m_Residual
Definition: NekNonlinSys.h:143
Array< OneD, NekDouble > m_DeltSltn
Definition: NekNonlinSys.h:144
Array< OneD, NekDouble > m_SourceVec
Definition: NekNonlinSys.h:145
NekLinSysIterSharedPtr m_linsol
Definition: NekNonlinSys.h:132
Array< OneD, NekDouble > m_Solution
Definition: NekNonlinSys.h:142
virtual void v_SetupNekNonlinSystem(const int nGlobal, const Array< OneD, const NekDouble > &pInput, const Array< OneD, const NekDouble > &pSource, const int nDir) override
void CalcInexactNewtonForcing(const int &k, NekDouble &resnormOld, const NekDouble &resnorm, NekDouble &forcing)
virtual int v_SolveSystem(const int nGlobal, const Array< OneD, const NekDouble > &pInput, Array< OneD, NekDouble > &pOutput, const int nDir, const NekDouble tol, const NekDouble factor) override
virtual bool v_ConvergenceCheck(const int nIteration, const Array< OneD, const NekDouble > &Residual, const NekDouble tol) override
bool m_root
Root if parallel.
Definition: NekSys.h:284
virtual void v_InitObject()
Definition: NekSys.h:293
bool m_verbose
Verbose.
Definition: NekSys.h:286
NekSysOperators m_operator
Operators.
Definition: NekSys.h:289
int m_SysDimen
The dimension of the system.
Definition: NekSys.h:291
LibUtilities::CommSharedPtr m_Comm
Communicate.
Definition: NekSys.h:280
bool m_converged
Whether the iteration has been converged.
Definition: NekSys.h:282
int m_maxiter
Maximum iterations.
Definition: NekSys.h:276
void DoNekSysResEval(InArrayType &inarray, OutArrayType &outarray, const bool &flag=false) const
Definition: NekSys.h:128
NekNonlinSysFactory & GetNekNonlinSysFactory()
std::shared_ptr< SessionReader > SessionReaderSharedPtr
std::shared_ptr< Comm > CommSharedPtr
Pointer to a Communicator object.
Definition: Comm.h:54
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:2
double NekDouble
T Dot(int n, const T *w, const T *x)
dot (vector times vector): z = w*x
Definition: Vmath.cpp:1100
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.cpp:1255
void Vsub(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Subtract vector z = x-y.
Definition: Vmath.cpp:419
scalarT< T > sqrt(scalarT< T > in)
Definition: scalar.hpp:294