LifeV
NonLinearRichardson.hpp
Go to the documentation of this file.
1 //@HEADER
2 /*
3 *******************************************************************************
4 
5  Copyright (C) 2004, 2005, 2007 EPFL, Politecnico di Milano, INRIA
6  Copyright (C) 2010 EPFL, Politecnico di Milano, Emory University
7 
8  This file is part of LifeV.
9 
10  LifeV is free software; you can redistribute it and/or modify
11  it under the terms of the GNU Lesser General Public License as published by
12  the Free Software Foundation, either version 3 of the License, or
13  (at your option) any later version.
14 
15  LifeV is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  Lesser General Public License for more details.
19 
20  You should have received a copy of the GNU Lesser General Public License
21  along with LifeV. If not, see <http://www.gnu.org/licenses/>.
22 
23 *******************************************************************************
24 */
25 //@HEADER
26 
27 /*!
28  @file
29  @brief Preconditioned relaxed solver for non linear problems.
30 
31  @author
32  @date 01-01-2004
33 
34  Given a functional this method tries to find a root near an
35  initial guess sol. The two methods that the functional must
36  have are evalRes and solveJac. If solveJac inverts the exact
37  Jacobian of the functional, than this is equivalent to a Newton
38  method. If convergence do not appens in the expected ratio,
39  a NonLinearLineSearch algorithm is called (uadratic or parabolic).
40 
41  @contributor Simone Deparis <simone.deparis@epfl.ch>
42  @maintainer Simone Deparis <simone.deparis@epfl.ch>
43 
44 
45  */
46 
47 #ifndef _NONLINEARRICHARDSON_HPP
48 #define _NONLINEARRICHARDSON_HPP
49 
50 #include <algorithm> // for min and max
51 #include <lifev/core/algorithm/NonLinearLineSearch.hpp>
52 #include <lifev/core/array/VectorEpetra.hpp>
53 
54 namespace LifeV
55 {
56 //! Preconditioned relaxed solver for non linear problems.
57 /*!
58  Add more details about the constructor.
59  NOTE: short description is automatically added before this part.
60  @param sol : the solution
61  @param maxit : input: maximum iterations, output: nb of iterations
62  @param abstol, reltol : the stoping criteria is abstol+reltol*norm(residual_0),
63  @param eta_max : Maximum error tolerance for residual in linear solver.
64 
65  The linear solver terminates when the relative
66  linear residual is smaller than eta*| f(sol) |.
67 
68  The value linear_rel_tol send for the relative tolerance
69  to the linear solver is therefore eta. eta is determined
70  by the modified Eisenstat-Walker formula if etamax > 0.
71 
72  @param NonLinearLineSearch : for now consider only the case NonLinearLineSearch=0
73  (coded but not theoretically analysed)
74 
75  @param omega : default relaxation parameter to be passed to Aitken.
76  if omega is negative, then its absolute value is
77  taken as constant relaxation parameter
78 
79  */
80 
81 template < class Fct >
82 Int NonLinearRichardson ( VectorEpetra& sol,
83  Fct& functional,
84  Real abstol,
85  Real reltol,
86  UInt& maxit,
87  Real eta_max,
88  Int NonLinearLineSearch,
89  UInt iter = UInt (0),
90  UInt verboseLevel = 0,
91  std::ostream& output = std::cout,
92  const Real& time = 0
93  )
94 {
95  /*
96  */
97 
98  /*
99  max_increase_res: maximum number of successive increases in residual
100  before failure is reported
101  */
102 
103  // const Int max_increase_res = 5;
104 
105  /*
106  Parameters for the linear solver, gamma: Default value = 0.9
107  */
108 
109  const Real gamma = 0.9;
110 
111  //----------------------------------------------------------------------
112 
113  if ( sol.comm().MyPID() != 0 )
114  {
115  verboseLevel = 0;
116  }
117 
118  VectorEpetra residual ( sol.map() );
119  VectorEpetra step ( sol.map() );
120 
121  step *= 0.;
122 
123  Real normResOld = 1;
124 
125  if ( verboseLevel > 0 )
126  {
127  std::cout << std::endl;
128  std::cout << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" << std::endl;
129  std::cout << " Non-Linear Richardson: starting " << std::endl;
130  std::cout << "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" << std::endl;
131  std::cout << std::endl;
132  }
133 
134  functional.evalResidual ( residual, sol, iter );
135 
136  Real normRes = residual.normInf();
137  Real stop_tol = abstol + reltol * normRes;
138  Real linearRelTol = std::fabs (eta_max);
139  Real eta_old;
140  Real eta_new;
141  Real ratio;
142  Real slope;
143  Real linres;
144  Real lambda;
145 
146  //
147 
148  Real solNormInf (sol.normInf() );
149  Real stepNormInf;
150  if ( verboseLevel > 1 )
151  {
152  output << std::scientific;
153  output << "# time = ";
154  output << time << " " << "initial norm_res " << normRes
155  << " rel tol = " << reltol
156  << " stop tol = " << stop_tol
157  << "initial norm_sol "
158  << solNormInf << std::endl;
159  output << "#iter disp_norm step_norm residual_norm" << std::endl;
160  }
161  while ( normRes > stop_tol && iter < maxit )
162  {
163  if ( verboseLevel > 0 )
164  {
165  std::cout << std::endl;
166  std::cout << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" << std::endl;
167  std::cout << " Non-Linear Richardson: iteration = " << iter << std::endl
168  << " residual = " << normRes << std::endl
169  << " rel tol = " << reltol << std::endl
170  << " abs tol = " << abstol << std::endl
171  << " tolerance = " << stop_tol << std::endl;
172  std::cout << "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" << std::endl;
173  std::cout << std::endl;
174  }
175 
176  iter++;
177 
178  ratio = normRes / normResOld;
179  normResOld = normRes;
180  normRes = residual.normInf();
181 
182  residual *= -1;
183 
184  functional.solveJac (step, residual, linearRelTol); // J*step = -R
185 
186  solNormInf = sol.normInf();
187  stepNormInf = step.normInf();
188  if ( verboseLevel > 1 )
189  {
190  output << std::setw (5) << iter
191  << std::setw (15) << solNormInf
192  << std::setw (15) << stepNormInf;
193  }
194  linres = linearRelTol;
195 
196  lambda = 1.;
197  slope = normRes * normRes * ( linres * linres - 1 );
198 
199  Int status (EXIT_SUCCESS);
200  switch ( NonLinearLineSearch )
201  {
202  case 0: // no NonLinearLineSearch
203  sol += step;
204  functional.evalResidual ( residual, sol, iter);
205  // normRes = residual.NormInf();
206  break;
207  case 1:
208  status = NonLinearLineSearchParabolic ( functional, residual, sol, step, normRes, lambda, iter, verboseLevel );
209  break;
210  case 2: // recommended
211  status = NonLinearLineSearchCubic ( functional, residual, sol, step, normRes, lambda, slope, iter, verboseLevel );
212  break;
213  default:
214  std::cout << "Unknown NonLinearLineSearch \n";
215  status = EXIT_FAILURE;
216  }
217 
218  if (status == EXIT_FAILURE)
219  {
220  return status;
221  }
222 
223  normRes = residual.normInf();
224 
225  if ( verboseLevel > 1 )
226  {
227  output << std::setw (15) << normRes << std::endl;
228  }
229 
230  if ( eta_max > 0 )
231  {
232  eta_old = linearRelTol;
233  eta_new = gamma * ratio * ratio;
234  if ( gamma * eta_old * eta_old > .1 )
235  {
236  eta_new = std::max<Real> ( eta_new, gamma * eta_old * eta_old );
237  }
238  linearRelTol = std::min<Real> ( eta_new, eta_max );
239  linearRelTol = std::min<Real> ( eta_max,
240  std::max<Real> ( linearRelTol,
241  .5 * stop_tol / normRes ) );
242  //if ( verboseLevel > 0 )
243  // std::cout << " Newton: forcing term eta = " << linearRelTol << std::endl;
244  //std::cout<<"\nVerbose = "<<verboseLevel<<std::endl;
245  }
246 
247  }
248 
249  if ( normRes > stop_tol )
250  {
251  if ( verboseLevel > 0 )
252  {
253  std::cout << "!!! NonLinRichardson: convergence fails" << std::endl;
254  }
255  maxit = iter;
256  return EXIT_FAILURE;
257  }
258 
259 
260  if ( verboseLevel > 0 )
261  {
262  std::cout << std::endl;
263  std::cout << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" << std::endl;
264  std::cout << " Non-Linear Richardson: convergence = " << normRes << std::endl
265  << " iterations = " << iter << std::endl;
266  std::cout << "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" << std::endl;
267  std::cout << std::endl;
268  }
269  // maxit = iter;
270 
271  return EXIT_SUCCESS;
272 }
273 }
274 #endif
int32_type Int
Generic integer data.
Definition: LifeV.hpp:188
double Real
Generic real data.
Definition: LifeV.hpp:175
uint32_type UInt
generic unsigned integer (used mainly for addressing)
Definition: LifeV.hpp:191