Reference documentation for deal.II version 9.3.3
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
solver_control.cc
Go to the documentation of this file.
1// ---------------------------------------------------------------------
2//
3// Copyright (C) 1998 - 2018 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.md at
12// the top level directory of deal.II.
13//
14// ---------------------------------------------------------------------
15
19
21
22#include <cmath>
23#include <sstream>
24
26
27/*----------------------- SolverControl ---------------------------------*/
28
29
30SolverControl::SolverControl(const unsigned int maxiter,
31 const double tolerance,
32 const bool m_log_history,
33 const bool m_log_result)
34 : maxsteps(maxiter)
35 , tol(tolerance)
36 , lcheck(failure)
37 , initial_val(numbers::signaling_nan<double>())
38 , lvalue(numbers::signaling_nan<double>())
40 , check_failure(false)
41 , relative_failure_residual(0)
42 , failure_residual(0)
43 , m_log_history(m_log_history)
44 , m_log_frequency(1)
45 , m_log_result(m_log_result)
46 , history_data_enabled(false)
47{}
48
49
50
52SolverControl::check(const unsigned int step, const double check_value)
53{
54 // if this is the first time we
55 // come here, then store the
56 // residual for later comparisons
57 if (step == 0)
58 {
59 initial_val = check_value;
60 }
61
62 if (m_log_history && ((step % m_log_frequency) == 0))
63 deallog << "Check " << step << "\t" << check_value << std::endl;
64
65 lstep = step;
66 lvalue = check_value;
67
68 if (step == 0)
69 {
70 if (check_failure)
72
73 if (m_log_result)
74 deallog << "Starting value " << check_value << std::endl;
75 }
76
78 history_data.push_back(check_value);
79
80 if (check_value <= tol)
81 {
82 if (m_log_result)
83 deallog << "Convergence step " << step << " value " << check_value
84 << std::endl;
86 return success;
87 }
88
89 if ((step >= maxsteps) || std::isnan(check_value) ||
90 (check_failure && (check_value > failure_residual)))
91 {
92 if (m_log_result)
93 deallog << "Failure step " << step << " value " << check_value
94 << std::endl;
96 return failure;
97 }
98
100 return iterate;
101}
102
103
104
107{
108 return lcheck;
109}
110
111
112double
114{
115 return initial_val;
116}
117
118
119double
121{
122 return lvalue;
123}
124
125
126unsigned int
128{
129 return lstep;
130}
131
132
133unsigned int
135{
136 if (f == 0)
137 f = 1;
138 unsigned int old = m_log_frequency;
139 m_log_frequency = f;
140 return old;
141}
142
143
144void
146{
148}
149
150
151
152const std::vector<double> &
154{
156 Assert(
157 history_data.size() > 0,
159 "The SolverControl object was asked for the solver history "
160 "data, but there is no data. Possibly you requested the data before the "
161 "solver was run."));
162
163 return history_data;
164}
165
166
167
168double
170{
171 if (lstep == 0)
172 return 0.;
173
178
179 return std::pow(history_data[lstep] / history_data[0], 1. / lstep);
180}
181
182
183
184double
185SolverControl::step_reduction(unsigned int step) const
186{
189 Assert(step <= lstep, ExcIndexRange(step, 1, lstep + 1));
190 Assert(step > 0, ExcIndexRange(step, 1, lstep + 1));
191
192 return history_data[step] / history_data[step - 1];
193}
194
195
196double
198{
199 return step_reduction(lstep);
200}
201
202
203void
205{
206 param.declare_entry("Max steps", "100", Patterns::Integer());
207 param.declare_entry("Tolerance", "1.e-10", Patterns::Double());
208 param.declare_entry("Log history", "false", Patterns::Bool());
209 param.declare_entry("Log frequency", "1", Patterns::Integer());
210 param.declare_entry("Log result", "true", Patterns::Bool());
211}
212
213
214void
216{
217 set_max_steps(param.get_integer("Max steps"));
218 set_tolerance(param.get_double("Tolerance"));
219 log_history(param.get_bool("Log history"));
220 log_result(param.get_bool("Log result"));
221 log_frequency(param.get_integer("Log frequency"));
222}
223
224/*----------------------- ReductionControl ---------------------------------*/
225
226
228 const double tol,
229 const double red,
230 const bool m_log_history,
231 const bool m_log_result)
232 : SolverControl(n, tol, m_log_history, m_log_result)
233 , reduce(red)
234 , reduced_tol(numbers::signaling_nan<double>())
235{}
236
237
239 : SolverControl(c)
240 , reduce(numbers::signaling_nan<double>())
241 , reduced_tol(numbers::signaling_nan<double>())
242{
243 set_reduction(0.);
244}
245
246
249{
251 set_reduction(0.);
252 return *this;
253}
254
255
256
258ReductionControl::check(const unsigned int step, const double check_value)
259{
260 // if this is the first time we
261 // come here, then store the
262 // residual for later comparisons
263 if (step == 0)
264 {
265 initial_val = check_value;
266 reduced_tol = check_value * reduce;
267 }
268
269 // check whether desired reduction
270 // has been achieved. also check
271 // for equality in case initial
272 // residual already was zero
273 if (check_value <= reduced_tol)
274 {
275 if (m_log_result)
276 deallog << "Convergence step " << step << " value " << check_value
277 << std::endl;
278 lstep = step;
279 lvalue = check_value;
280 lcheck = success;
281
283 history_data.push_back(check_value);
284
285 return success;
286 }
287 else
288 return SolverControl::check(step, check_value);
289}
290
291
292
293void
295{
297 param.declare_entry("Reduction", "1.e-2", Patterns::Double());
298}
299
300
301void
303{
305 set_reduction(param.get_double("Reduction"));
306}
307
308
309/*---------------------- IterationNumberControl -----------------------------*/
310
311
313 const double tolerance,
314 const bool m_log_history,
315 const bool m_log_result)
316 : SolverControl(n, tolerance, m_log_history, m_log_result)
317{}
318
319
320
322IterationNumberControl::check(const unsigned int step, const double check_value)
323{
324 // check whether the given number of iterations was reached, and return
325 // success in that case. Otherwise, go on to the check of the base class.
326 if (step >= this->maxsteps)
327 {
328 if (m_log_result)
329 deallog << "Convergence step " << step << " value " << check_value
330 << std::endl;
331 lstep = step;
332 lvalue = check_value;
333
334 lcheck = success;
335 return success;
336 }
337 else
338 return SolverControl::check(step, check_value);
339}
340
341/*------------------------ ConsecutiveControl -------------------------------*/
342
343
345 const unsigned int n,
346 const double tolerance,
347 const unsigned int n_consecutive_iterations,
348 const bool m_log_history,
349 const bool m_log_result)
350 : SolverControl(n, tolerance, m_log_history, m_log_result)
351 , n_consecutive_iterations(n_consecutive_iterations)
352 , n_converged_iterations(0)
353{
355 ExcMessage("n_consecutive_iterations should be positive"));
356}
357
358
359
361 : SolverControl(c)
362 , n_consecutive_iterations(1)
363 , n_converged_iterations(0)
364{}
365
366
367
370{
374 return *this;
375}
376
377
378
380ConsecutiveControl::check(const unsigned int step, const double check_value)
381{
382 // reset the counter if ConsecutiveControl is being reused
383 if (step == 0)
385 else
386 {
387 // check two things:
388 // (i) steps are ascending without repetitions
389 // (ii) user started from zero even when solver is being reused.
390 Assert(step - 1 == lstep,
391 ExcMessage("steps should be ascending integers."));
392 }
393
394 SolverControl::State state = SolverControl::check(step, check_value);
395 // check if we need to override the success:
396 if (state == success)
397 {
400 {
401 return success;
402 }
403 else
404 {
405 lcheck = iterate;
406 return iterate;
407 }
408 }
409 else
410 {
412 return state;
413 }
414}
415
ConsecutiveControl & operator=(const SolverControl &c)
ConsecutiveControl(const unsigned int maxiter=100, const double tolerance=1.e-10, const unsigned int n_consecutive_iterations=2, const bool log_history=false, const bool log_result=false)
unsigned int n_consecutive_iterations
unsigned int n_converged_iterations
virtual State check(const unsigned int step, const double check_value) override
virtual State check(const unsigned int step, const double check_value) override
IterationNumberControl(const unsigned int maxiter=100, const double tolerance=1e-12, const bool log_history=false, const bool log_result=true)
long int get_integer(const std::string &entry_string) const
bool get_bool(const std::string &entry_name) const
void declare_entry(const std::string &entry, const std::string &default_value, const Patterns::PatternBase &pattern=Patterns::Anything(), const std::string &documentation="", const bool has_to_be_set=false)
double get_double(const std::string &entry_name) const
double set_reduction(const double)
void parse_parameters(ParameterHandler &param)
virtual State check(const unsigned int step, const double check_value) override
static void declare_parameters(ParameterHandler &param)
ReductionControl & operator=(const SolverControl &c)
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)
static void declare_parameters(ParameterHandler &param)
State last_check() const
double average_reduction() const
const std::vector< double > & get_history_data() const
unsigned int lstep
unsigned int last_step() const
double last_value() const
unsigned int m_log_frequency
unsigned int log_frequency(unsigned int)
virtual State check(const unsigned int step, const double check_value)
unsigned int maxsteps
bool log_history() const
void enable_history_data()
double step_reduction(unsigned int step) const
std::vector< double > history_data
double failure_residual
double relative_failure_residual
unsigned int set_max_steps(const unsigned int)
double set_tolerance(const double)
SolverControl(const unsigned int n=100, const double tol=1.e-10, const bool log_history=false, const bool log_result=true)
double initial_value() const
bool log_result() const
void parse_parameters(ParameterHandler &param)
double final_reduction() const
@ iterate
Continue iteration.
@ success
Stop iteration, goal reached.
@ failure
Stop iteration, goal not reached.
bool history_data_enabled
Subscriptor & operator=(const Subscriptor &)
Definition: subscriptor.h:292
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:402
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:403
static ::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
#define Assert(cond, exc)
Definition: exceptions.h:1465
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcHistoryDataRequired()
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
Definition: exceptions.h:1575
LogStream deallog
Definition: logstream.cc:37
static const unsigned int invalid_unsigned_int
Definition: types.h:196
T signaling_nan()
::VectorizedArray< Number, width > pow(const ::VectorizedArray< Number, width > &, const Number p)