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 }
62 
64 {
69 }
70 
72 {
73 }
74 
75 /**
76  *
77  **/
79  const int nGlobal, const Array<OneD, const NekDouble> &pInput,
80  Array<OneD, NekDouble> &pOutput, const int nDir, const NekDouble tol,
81  const NekDouble factor)
82 {
83  boost::ignore_unused(factor);
84 
85  int nwidthcolm = 11;
86 
87  v_SetupNekNonlinSystem(nGlobal, pInput, pInput, nDir);
88 
89  m_Solution = pOutput;
90  Vmath::Vcopy(nGlobal-nDir, pInput, 1, m_Solution, 1);
91 
92  int ntotal = nGlobal - nDir;
93  m_NtotLinSysIts = 0;
94 
95  int NttlNonlinIte = 0;
96  m_converged = false;
97 
98  NekDouble resnormOld = 0.0;
99  for (int k = 0; k < m_maxiter; ++k)
100  {
102  if (m_converged)
103  break;
104 
105  NekDouble LinSysRelativeIteTol;
106  CalcInexactNewtonForcing(k, resnormOld, m_SysResNorm,
107  LinSysRelativeIteTol);
108 
109  resnormOld = m_SysResNorm;
110 
111  NekDouble LinSysTol = LinSysRelativeIteTol * sqrt(m_SysResNorm);
112  int ntmpLinSysIts =
113  m_linsol->SolveSystem(ntotal, m_Residual, m_DeltSltn, 0, LinSysTol);
114  m_NtotLinSysIts += ntmpLinSysIts;
115  Vmath::Vsub(ntotal, m_Solution, 1, m_DeltSltn, 1, m_Solution, 1);
116  NttlNonlinIte++;
118  }
119 
120  if ( ((!m_converged) || m_verbose) && m_root && m_FlagWarnings)
121  {
123  " # Nonlinear solver not converge in DoImplicitSolve");
124  cout << right << scientific << setw(nwidthcolm)
125  << setprecision(nwidthcolm - 6)
126  << " * Newton-Its converged (RES=" << sqrt(m_SysResNorm)
127  << " Res/(DtRHS): " << sqrt(m_SysResNorm / m_SysResNorm0)
128  << " with " << setw(3) << NttlNonlinIte << " Non-Its)" << endl;
129  }
130 
131  m_ResidualUpdated = false;
132  return NttlNonlinIte;
133 }
134 
136  const int nIteration, const Array<OneD, const NekDouble> &Residual,
137  const NekDouble tol)
138 {
139  bool converged = false;
140  NekDouble resratio = 1.0;
141  int ntotal = Residual.size();
142 
143  m_SysResNorm = Vmath::Dot(ntotal, Residual, Residual);
145 
146  if (0 == nIteration)
147  {
149  resratio = 1.0;
150  }
151  else
152  {
153  resratio = m_SysResNorm / m_SysResNorm0;
154  }
155 
157  m_SysResNorm < tol)
158  {
159  converged = true;
160  }
161 
162  return converged;
163 }
164 
166  const int &k,
167  NekDouble &resnormOld,
168  const NekDouble &resnorm,
169  NekDouble &forcing)
170 {
171  if (0 == k)
172  {
173  forcing = m_LinSysRelativeTolInNonlin;
174  resnormOld = resnorm;
175  }
176  else
177  {
178  switch(m_InexactNewtonForcing)
179  {
180  case 0:
181  {
182  forcing = m_LinSysRelativeTolInNonlin;
183  break;
184  }
185  case 1:
186  {
187  NekDouble tmpForc = m_forcingGamma *
188  pow((resnorm / resnormOld), m_forcingAlpha);
189  NekDouble tmp = m_forcingGamma *
190  pow(forcing, m_forcingAlpha);
191  if (tmp > 0.1)
192  {
193  forcing = min(m_LinSysRelativeTolInNonlin,
194  max(tmp, tmpForc));
195  }
196  else
197  {
198  forcing = min(m_LinSysRelativeTolInNonlin, tmpForc);
199  }
200 
201  forcing = max(forcing, 1.0E-6);
202  break;
203  }
204  }
205  }
206 }
207 
209  const int nGlobal, const Array<OneD, const NekDouble> &pInput,
210  const Array<OneD, const NekDouble> &pSource,
211  const int nDir)
212 {
213  boost::ignore_unused(nGlobal, nDir);
214 
215  ASSERTL0(0 == nDir, "0 != nDir not tested");
216  ASSERTL0(m_SysDimen == nGlobal, "m_SysDimen!=nGlobal");
217 
218  m_SourceVec = pSource;
219  Vmath::Vcopy(nGlobal-nDir, pSource, 1, m_SourceVec, 1);
220 
221  if (!m_ResidualUpdated)
222  {
224  m_ResidualUpdated = true;
225  }
226  m_linsol->SetSysOperators(m_operator);
227 }
228 
229 
230 } // namespace LibUtilities
231 } // namespace Nektar
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
#define WARNINGL0(condition, msg)
Definition: ErrorUtil.hpp:223
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
Definition: NekFactory.hpp:200
Array< OneD, NekDouble > m_Residual
Definition: NekNonlinSys.h:155
Array< OneD, NekDouble > m_DeltSltn
Definition: NekNonlinSys.h:156
Array< OneD, NekDouble > m_SourceVec
Definition: NekNonlinSys.h:157
NekLinSysIterSharedPtr m_linsol
Definition: NekNonlinSys.h:143
Array< OneD, NekDouble > m_Solution
Definition: NekNonlinSys.h:154
virtual bool v_ConvergenceCheck(const int nIteration, const Array< OneD, const NekDouble > &Residual, const NekDouble tol)
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)
virtual void v_SetupNekNonlinSystem(const int nGlobal, const Array< OneD, const NekDouble > &pInput, const Array< OneD, const NekDouble > &pSource, const int nDir)
bool m_root
Root if parallel.
Definition: NekSys.h:289
virtual void v_InitObject()
Definition: NekSys.h:298
bool m_verbose
Verbose.
Definition: NekSys.h:291
NekSysOperators m_operator
Operators.
Definition: NekSys.h:294
int m_SysDimen
The dimension of the system.
Definition: NekSys.h:296
LibUtilities::CommSharedPtr m_Comm
Communicate.
Definition: NekSys.h:285
bool m_converged
Whether the iteration has been converged.
Definition: NekSys.h:287
int m_maxiter
Maximum iterations.
Definition: NekSys.h:281
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:1
double NekDouble
T Dot(int n, const T *w, const T *x)
vvtvp (vector times vector times vector): z = w*x*y
Definition: Vmath.cpp:1038
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.cpp:1199
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:372
scalarT< T > sqrt(scalarT< T > in)
Definition: scalar.hpp:267