Reference documentation for deal.II version 8.4.2
solver_control.cc
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 1998 - 2015 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE at
12 // the top level of the deal.II distribution.
13 //
14 // ---------------------------------------------------------------------
15 
16 #include <deal.II/base/logstream.h>
17 #include <deal.II/base/parameter_handler.h>
18 #include <deal.II/lac/solver_control.h>
19 
20 #include <cmath>
21 #include <sstream>
22 
23 DEAL_II_NAMESPACE_OPEN
24 
25 /*----------------------- SolverControl ---------------------------------*/
26 
27 
28 SolverControl::SolverControl (const unsigned int maxiter,
29  const double tolerance,
30  const bool m_log_history,
31  const bool m_log_result)
32  :
33  maxsteps(maxiter),
34  tol(tolerance),
35  lvalue(1.e300),
36  lstep(0),
37  check_failure(false),
38  relative_failure_residual(0),
39  failure_residual(0),
40  m_log_history(m_log_history),
41  m_log_frequency(1),
42  m_log_result(m_log_result),
43  history_data_enabled(false)
44 {}
45 
46 
47 
49 {}
50 
51 
52 
54 SolverControl::check (const unsigned int step,
55  const double check_value)
56 {
57  // if this is the first time we
58  // come here, then store the
59  // residual for later comparisons
60  if (step==0)
61  {
62  initial_val = check_value;
64  history_data.resize(maxsteps);
65  }
66 
67  if (m_log_history && ((step % m_log_frequency) == 0))
68  deallog << "Check " << step << "\t" << check_value << std::endl;
69 
70  lstep = step;
71  lvalue = check_value;
72 
73  if (step==0)
74  {
75  if (check_failure)
77 
78  if (m_log_result)
79  deallog << "Starting value " << check_value << std::endl;
80  }
81 
83  history_data[step] = check_value;
84 
85  if (check_value <= tol)
86  {
87  if (m_log_result)
88  deallog << "Convergence step " << step
89  << " value " << check_value << std::endl;
90  lcheck = success;
91  return success;
92  }
93 
94  if ((step >= maxsteps) ||
95  numbers::is_nan(check_value) ||
96  (check_failure && (check_value > failure_residual))
97  )
98  {
99  if (m_log_result)
100  deallog << "Failure step " << step
101  << " value " << check_value << std::endl;
102  lcheck = failure;
103  return failure;
104  }
105 
106  lcheck = iterate;
107  return iterate;
108 }
109 
110 
111 
114 {
115  return lcheck;
116 }
117 
118 
119 double
121 {
122  return initial_val;
123 }
124 
125 
126 double
128 {
129  return lvalue;
130 }
131 
132 
133 unsigned int
135 {
136  return lstep;
137 }
138 
139 
140 unsigned int
142 {
143  if (f==0)
144  f = 1;
145  unsigned int old = m_log_frequency;
146  m_log_frequency = f;
147  return old;
148 }
149 
150 
151 void
153 {
154  history_data_enabled = true;
155 }
156 
157 
158 double
160 {
161  if (lstep == 0)
162  return 0.;
163 
164  Assert (history_data_enabled, ExcHistoryDataRequired());
165  Assert (history_data.size() > lstep, ExcInternalError());
166  Assert (history_data[0] > 0., ExcInternalError());
167  Assert (history_data[lstep] > 0., ExcInternalError());
168 
169  return std::pow(history_data[lstep]/history_data[0], 1./lstep);
170 }
171 
172 
173 
174 double
175 SolverControl::step_reduction(unsigned int step) const
176 {
177  Assert (history_data_enabled, ExcHistoryDataRequired());
178  Assert (history_data.size() > lstep, ExcInternalError());
179  Assert (step <=lstep, ExcIndexRange(step,1,lstep+1));
180  Assert (step>0, ExcIndexRange(step,1,lstep+1));
181 
182  return history_data[step]/history_data[@ref step_1 "step-1"];
183 }
184 
185 
186 double
188 {
189  return step_reduction(lstep);
190 }
191 
192 
193 void
195 {
196  param.declare_entry ("Max steps", "100", Patterns::Integer());
197  param.declare_entry ("Tolerance", "1.e-10", Patterns::Double());
198  param.declare_entry ("Log history", "false", Patterns::Bool());
199  param.declare_entry ("Log frequency", "1", Patterns::Integer());
200  param.declare_entry ("Log result", "true", Patterns::Bool());
201 }
202 
203 
205 {
206  set_max_steps (param.get_integer("Max steps"));
207  set_tolerance (param.get_double("Tolerance"));
208  log_history (param.get_bool("Log history"));
209  log_result (param.get_bool("Log result"));
210  log_frequency (param.get_integer("Log frequency"));
211 }
212 
213 /*----------------------- ReductionControl ---------------------------------*/
214 
215 
217  const double tol,
218  const double red,
219  const bool m_log_history,
220  const bool m_log_result)
221  :
222  SolverControl (n, tol, m_log_history, m_log_result),
223  reduce(red)
224 {}
225 
226 
228  :
229  SolverControl(c)
230 {
231  set_reduction(0.);
232 }
233 
234 
237 {
239  set_reduction(0.);
240  return *this;
241 }
242 
243 
245 {}
246 
247 
249 ReductionControl::check (const unsigned int step,
250  const double check_value)
251 {
252  // if this is the first time we
253  // come here, then store the
254  // residual for later comparisons
255  if (step==0)
256  {
257  initial_val = check_value;
258  reduced_tol = check_value * reduce;
259  };
260 
261  // check whether desired reduction
262  // has been achieved. also check
263  // for equality in case initial
264  // residual already was zero
265  if (check_value <= reduced_tol)
266  {
267  if (m_log_result)
268  deallog << "Convergence step " << step
269  << " value " << check_value << std::endl;
270  lstep = step;
271  lvalue = check_value;
272 
273  lcheck = success;
274  return success;
275  }
276  else
277  return SolverControl::check(step, check_value);
278 }
279 
280 
281 
282 void
284 {
286  param.declare_entry("Reduction", "1.e-2", Patterns::Double());
287 }
288 
289 
290 void
292 {
294  set_reduction (param.get_double("Reduction"));
295 }
296 
297 
298 /*---------------------- IterationNumberControl -----------------------------*/
299 
300 
302  const double tolerance,
303  const bool m_log_history,
304  const bool m_log_result)
305  :
306  SolverControl (n, tolerance, m_log_history, m_log_result) {}
307 
308 
310 {}
311 
312 
314 IterationNumberControl::check (const unsigned int step,
315  const double check_value)
316 {
317  // check whether the given number of iterations was reached, and return
318  // success in that case. Otherwise, go on to the check of the base class.
319  if (step >= this->maxsteps)
320  {
321  if (m_log_result)
322  deallog << "Convergence step " << step
323  << " value " << check_value << std::endl;
324  lstep = step;
325  lvalue = check_value;
326 
327  lcheck = success;
328  return success;
329  }
330  else
331  return SolverControl::check(step, check_value);
332 }
333 
334 DEAL_II_NAMESPACE_CLOSE
double initial_value() const
Stop iteration, goal not reached.
long int get_integer(const std::string &entry_string) const
bool log_history() const
virtual State check(const unsigned int step, const double check_value)
bool history_data_enabled
Continue iteration.
Subscriptor & operator=(const Subscriptor &)
Definition: subscriptor.cc:144
static void declare_parameters(ParameterHandler &param)
double step_reduction(unsigned int step) const
double final_reduction() const
void parse_parameters(ParameterHandler &param)
double failure_residual
double get_double(const std::string &entry_name) const
static void declare_parameters(ParameterHandler &param)
unsigned int log_frequency(unsigned int)
Stop iteration, goal reached.
#define Assert(cond, exc)
Definition: exceptions.h:294
unsigned int m_log_frequency
double set_reduction(const double)
virtual ~ReductionControl()
bool is_nan(const double x)
Definition: numbers.h:242
bool get_bool(const std::string &entry_name) const
double relative_failure_residual
double last_value() const
double average_reduction() const
unsigned int lstep
double tolerance() const
unsigned int last_step() const
IterationNumberControl(const unsigned int maxiter=100, const double tolerance=1e-12, const bool log_history=false, const bool log_result=true)
State last_check() const
virtual ~SolverControl()
void declare_entry(const std::string &entry, const std::string &default_value, const Patterns::PatternBase &pattern=Patterns::Anything(), const std::string &documentation=std::string())
void enable_history_data()
double set_tolerance(const double)
ReductionControl(const unsigned int maxiter=100, const double tolerance=1.e-10, const double reduce=1.e-2, const bool log_history=false, const bool log_result=true)
unsigned int maxsteps
virtual State check(const unsigned int step, const double check_value)
void parse_parameters(ParameterHandler &param)
std::vector< double > history_data
SolverControl(const unsigned int n=100, const double tol=1.e-10, const bool log_history=false, const bool log_result=true)
bool log_result() const
unsigned int set_max_steps(const unsigned int)
virtual State check(const unsigned int step, const double check_value)
ReductionControl & operator=(const SolverControl &c)