DOpE
newtonsolver.h
Go to the documentation of this file.
1 
24 #ifndef NEWTON_SOLVER_H_
25 #define NEWTON_SOLVER_H_
26 
27 #include <deal.II/lac/vector.h>
28 #include <deal.II/lac/block_sparsity_pattern.h>
29 #include <deal.II/lac/block_sparse_matrix.h>
30 #include <deal.II/numerics/vector_tools.h>
31 #include <vector>
32 #include <iostream>
33 #include <fstream>
34 #include <iomanip>
35 
36 #include "parameterreader.h"
37 
38 
39 
40 
41 namespace DOpE
42 {
52  template <typename INTEGRATOR, typename LINEARSOLVER, typename VECTOR>
53  class NewtonSolver : public LINEARSOLVER
54  {
55  public:
56  NewtonSolver(INTEGRATOR &integrator, ParameterReader &param_reader);
57  ~NewtonSolver();
58 
59  static void declare_params(ParameterReader &param_reader);
60 
65  template<typename PROBLEM>
66  void ReInit(PROBLEM& pde);
67 
95  template<typename PROBLEM>
96  bool NonlinearSolve(PROBLEM& pde, VECTOR &solution, bool apply_boundary_values=true,
97  bool force_matrix_build=false,
98  int priority = 5, std::string algo_level = "\t\t ");
99 
100  protected:
101 
102  inline INTEGRATOR& GetIntegrator();
103 
104  private:
105  INTEGRATOR &integrator_;
106 
107  bool build_matrix_;
108 
109  double nonlinear_global_tol_, nonlinear_tol_, nonlinear_rho_;
110  double linesearch_rho_;
111  int nonlinear_maxiter_, line_maxiter_;
112  };
113 
114  /**********************************Implementation*******************************************/
115 
116 template <typename INTEGRATOR, typename LINEARSOLVER, typename VECTOR>
119  {
120  param_reader.SetSubsection("newtonsolver parameters");
121  param_reader.declare_entry("nonlinear_global_tol", "1.e-12",Patterns::Double(0),"global tolerance for the newton iteration");
122  param_reader.declare_entry("nonlinear_tol", "1.e-10",Patterns::Double(0),"relative tolerance for the newton iteration");
123  param_reader.declare_entry("nonlinear_maxiter", "10",Patterns::Integer(0),"maximal number of newton iterations");
124  param_reader.declare_entry("nonlinear_rho", "0.1",Patterns::Double(0),"minimal newton reduction, if actual reduction is less, matrix is rebuild ");
125 
126  param_reader.declare_entry("line_maxiter", "4",Patterns::Integer(0),"maximal number of linesearch steps");
127  param_reader.declare_entry("linesearch_rho", "0.9",Patterns::Double(0),"reduction rate for the linesearch damping paramete");
128 
129  LINEARSOLVER::declare_params(param_reader);
130  }
131 
132  /*******************************************************************************************/
133 
134  template <typename INTEGRATOR, typename LINEARSOLVER, typename VECTOR>
136  ::NewtonSolver(INTEGRATOR &integrator, ParameterReader &param_reader)
137  : LINEARSOLVER(param_reader), integrator_(integrator)
138  {
139  param_reader.SetSubsection("newtonsolver parameters");
140  nonlinear_global_tol_ = param_reader.get_double ("nonlinear_global_tol");
141  nonlinear_tol_ = param_reader.get_double ("nonlinear_tol");
142  nonlinear_maxiter_ = param_reader.get_integer ("nonlinear_maxiter");
143  nonlinear_rho_ = param_reader.get_double ("nonlinear_rho");
144 
145  line_maxiter_ = param_reader.get_integer ("line_maxiter");
146  linesearch_rho_ = param_reader.get_double ("linesearch_rho");
147 
148  }
149 
150  /*******************************************************************************************/
151 
152  template <typename INTEGRATOR, typename LINEARSOLVER, typename VECTOR>
155  {
156  }
157 
158  /*******************************************************************************************/
159  template <typename INTEGRATOR, typename LINEARSOLVER, typename VECTOR>
160  template<typename PROBLEM>
162  ::ReInit(PROBLEM& pde)
163  {
164  LINEARSOLVER::ReInit(pde);
165  }
166 
167  /*******************************************************************************************/
168  template <typename INTEGRATOR, typename LINEARSOLVER, typename VECTOR>
169  template<typename PROBLEM>
171  ::NonlinearSolve(PROBLEM& pde,
172  VECTOR &solution,
173  bool apply_boundary_values,
174  bool force_matrix_build,
175  int priority,
176  std::string algo_level)
177  {
178  bool build_matrix = force_matrix_build;
179  VECTOR residual;
180  VECTOR du;
181  std::stringstream out;
182  pde.GetOutputHandler()->InitNewtonOut(out);
183 
184  du.reinit(solution);
185  residual.reinit(solution);
186 
187  if(apply_boundary_values)
188  {
189  GetIntegrator().ApplyInitialBoundaryValues(pde,solution);
190  }
191  pde.GetDoFConstraints().distribute(solution);
192 
193  GetIntegrator().AddDomainData("last_newton_solution",&solution);
194 
195  GetIntegrator().ComputeNonlinearResidual(pde,residual);
196  residual *= -1.;
197 
198  pde.GetOutputHandler()->SetIterationNumber(0,"PDENewton");
199  pde.GetOutputHandler()->Write(residual,"Residual"+pde.GetType(),pde.GetDoFType());
200 
201  double res = residual.linfty_norm();
202  double firstres = res;
203  double lastres = res;
204 
205 
206  out<< algo_level << "Newton step: " <<0<<"\t Residual (abs.): "
207  <<pde.GetOutputHandler()->ZeroTolerance(res, 1.0)
208  <<"\n";
209 
210  out<< algo_level << "Newton step: " <<0<<"\t Residual (rel.): " << std::scientific << firstres/firstres;
211 
212 
213  pde.GetOutputHandler()->Write(out,priority);
214 
215  int iter=0;
216  while(res > nonlinear_global_tol_ && res > firstres * nonlinear_tol_)
217  {
218  iter++;
219 
220  if(iter > nonlinear_maxiter_)
221  {
222  GetIntegrator().DeleteDomainData("last_newton_solution");
223  throw DOpEIterationException("Iteration count exceeded bounds!","NewtonSolver::NonlinearSolve");
224  }
225 
226  pde.GetOutputHandler()->SetIterationNumber(iter,"PDENewton");
227 
228  LINEARSOLVER::Solve(pde,GetIntegrator(),residual,du,build_matrix);
229  build_matrix = false;
230 
231  //Linesearch
232  {
233  solution += du;
234  GetIntegrator().ComputeNonlinearResidual(pde,residual);
235  residual *= -1.;
236 
237  pde.GetOutputHandler()->Write(residual,"Residual"+pde.GetType(),pde.GetDoFType());
238  pde.GetOutputHandler()->Write(du,"Update"+pde.GetType(),pde.GetDoFType());
239 
240  double newres = residual.linfty_norm();
241  int lineiter=0;
242  double rho = linesearch_rho_;
243  double alpha=1;
244 
245  while(newres > res)
246  {
247  out<< algo_level << "Newton step: " <<iter<<"\t Residual (rel.): "
248  <<pde.GetOutputHandler()->ZeroTolerance(newres/firstres, 1.0)
249  << "\t LineSearch {"<<lineiter<<"} ";
250 
251  pde.GetOutputHandler()->Write(out,priority+1);
252 
253  lineiter++;
254  if(lineiter > line_maxiter_)
255  {
256  GetIntegrator().DeleteDomainData("last_newton_solution");
257  throw DOpEIterationException("Line-Iteration count exceeded bounds!","NewtonSolver::NonlinearSolve");
258  }
259  solution.add(alpha*(rho-1.),du);
260  alpha*= rho;
261 
262  GetIntegrator().ComputeNonlinearResidual(pde,residual);
263  residual *= -1.;
264  pde.GetOutputHandler()->Write(residual,"Residual"+pde.GetType(),pde.GetDoFType());
265 
266  newres = residual.linfty_norm();
267 
268  }
269  if(res/lastres > nonlinear_rho_)
270  {
271  build_matrix=true;
272  }
273  lastres=res;
274  res=newres;
275 
276  out << algo_level
277  << "Newton step: "
278  <<iter
279  <<"\t Residual (rel.): "
280  << pde.GetOutputHandler()->ZeroTolerance(res/firstres, 1.0)
281  << "\t LineSearch {"
282  <<lineiter
283  <<"} ";
284 
285 
286  pde.GetOutputHandler()->Write(out,priority);
287 
288  }//End of Linesearch
289  }
290  GetIntegrator().DeleteDomainData("last_newton_solution");
291 
292  return build_matrix;
293  }
294 
295  /*******************************************************************************************/
296  template <typename INTEGRATOR, typename LINEARSOLVER, typename VECTOR>
299  {
300  return integrator_;
301  }
302 
303  /*******************************************************************************************/
304 
305 }
306 #endif
307 
308 
309 
310 
311 
Definition: dopeexception.h:76
double get_double(const std::string &entry_name)
Definition: parameterreader.h:115
void ReInit(PROBLEM &pde)
Definition: newtonsolver.h:162
Definition: parameterreader.h:36
INTEGRATOR & GetIntegrator()
Definition: newtonsolver.h:298
~NewtonSolver()
Definition: newtonsolver.h:154
void declare_entry(const std::string &entry, const std::string &default_value, const Patterns::PatternBase &pattern=Patterns::Anything(), const std::string &documentation=std::string())
Definition: parameterreader.h:98
Definition: newtonsolver.h:53
int get_integer(const std::string &entry_name)
Definition: parameterreader.h:126
NewtonSolver(INTEGRATOR &integrator, ParameterReader &param_reader)
Definition: newtonsolver.h:136
static void declare_params(ParameterReader &param_reader)
Definition: newtonsolver.h:118
void SetSubsection(const std::string subsection)
Definition: parameterreader.h:93
bool NonlinearSolve(PROBLEM &pde, VECTOR &solution, bool apply_boundary_values=true, bool force_matrix_build=false, int priority=5, std::string algo_level="\t\t ")
Definition: newtonsolver.h:171