Line data Source code
1 : /*
2 : * Copyright (c) 2010-2015: G-CSC, Goethe University Frankfurt
3 : * Author: Andreas Vogel
4 : *
5 : * This file is part of UG4.
6 : *
7 : * UG4 is free software: you can redistribute it and/or modify it under the
8 : * terms of the GNU Lesser General Public License version 3 (as published by the
9 : * Free Software Foundation) with the following additional attribution
10 : * requirements (according to LGPL/GPL v3 §7):
11 : *
12 : * (1) The following notice must be displayed in the Appropriate Legal Notices
13 : * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
14 : *
15 : * (2) The following notice must be displayed at a prominent place in the
16 : * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
17 : *
18 : * (3) The following bibliography is recommended for citation and must be
19 : * preserved in all covered files:
20 : * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
21 : * parallel geometric multigrid solver on hierarchically distributed grids.
22 : * Computing and visualization in science 16, 4 (2013), 151-164"
23 : * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
24 : * flexible software system for simulating pde based models on high performance
25 : * computers. Computing and visualization in science 16, 4 (2013), 165-179"
26 : *
27 : * This program is distributed in the hope that it will be useful,
28 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 : * GNU Lesser General Public License for more details.
31 : */
32 :
33 : /*
34 : * Comment: Based on an idea by Arne Naegel
35 : */
36 :
37 : #ifndef __H__LIB_ALGEBRA__OPERATOR__CONVERGENCE_CHECK__
38 : #define __H__LIB_ALGEBRA__OPERATOR__CONVERGENCE_CHECK__
39 :
40 : #include <ostream>
41 : #include <sstream>
42 : #include <string>
43 : #include <limits>
44 : #include <algorithm>
45 : #include <iomanip>
46 : #include <vector>
47 : #include <list>
48 : #include <math.h>
49 :
50 : #include "common/common.h"
51 : #include "common/stopwatch.h"
52 : #include "lib_disc/function_spaces/approximation_space.h"
53 : #include "lib_disc/common/function_group.h"
54 :
55 : namespace ug{
56 :
57 : ///////////////////////////////////////////////////////////////////////////////
58 : ///////////////////////////////////////////////////////////////////////////////
59 : // Convergence check
60 : ///////////////////////////////////////////////////////////////////////////////
61 : ///////////////////////////////////////////////////////////////////////////////
62 :
63 : /** IConvergenceCheck
64 : *
65 : * This is the base class for a convergence checking object. An instance is
66 : * passed to an iterative solver to control the convergence.
67 : *
68 : * \tparam TVector vector type
69 : */
70 : template <typename TVector>
71 : class IConvergenceCheck
72 : {
73 : public:
74 : /// sets the given start defect
75 : virtual void start_defect(number defect) = 0;
76 :
77 : /// computes the start defect and set it
78 : virtual void start(const TVector& d) = 0;
79 :
80 : /// sets the update for the current defect
81 : virtual void update_defect(number defect) = 0;
82 :
83 : /// computes the defect and sets it a the next defect value
84 : virtual void update(const TVector& d) = 0;
85 :
86 : /** iteration_ended
87 : *
88 : * Checks if the iteration must be ended.
89 : * This can be due to convergence or divergence.
90 : *
91 : * \return true if iteration ended
92 : * false if iteration can and must be continued until convergence
93 : */
94 : virtual bool iteration_ended() = 0;
95 :
96 : /** post
97 : *
98 : * post-processes the iteration. Some informative outputs of the status of
99 : * the iteration after finishing the iteration can be placed here
100 : *
101 : * \return true if iteration was successful
102 : * false if iteration did not lead to a satisfying result
103 : */
104 : virtual bool post() = 0;
105 :
106 : /////////////////////////////////////
107 : // informations about current status
108 : /////////////////////////////////////
109 :
110 : /// returns the current defect
111 : virtual number defect() const = 0;
112 :
113 : /// returns the current number of steps
114 : virtual int step() const = 0;
115 :
116 : // returns the current relative reduction
117 : virtual number reduction() const = 0;
118 :
119 : // returns the current convergence rate
120 : virtual number rate() const = 0;
121 :
122 : // returns the averaged convergence rate
123 : virtual number avg_rate() const = 0;
124 :
125 : ////////////////
126 : // output style
127 : ////////////////
128 :
129 : /// sets the number of spaces printed before output information
130 : virtual void set_offset(int offset) = 0;
131 :
132 : /// get the current offset
133 : virtual int get_offset() const = 0;
134 :
135 : /// sets the symbol used for output
136 : virtual void set_symbol(char symbol) = 0;
137 :
138 : /// sets the name of the iteration
139 : virtual void set_name(std::string name) = 0;
140 :
141 : /// sets info string
142 : virtual void set_info(std::string name) = 0;
143 :
144 : /// prints a line
145 : virtual void print_line(std::string line) = 0;
146 :
147 : /// clone the object
148 : virtual SmartPtr<IConvergenceCheck<TVector> > clone() = 0;
149 :
150 : /// virtual destructor
151 : virtual ~IConvergenceCheck() {};
152 :
153 : /// returns information about configuration parameters
154 : /**
155 : * this should return necessary information about parameters and possibly
156 : * calling config_string of subcomponents.
157 : *
158 : * \returns std::string necessary information about configuration parameters
159 : */
160 :
161 : virtual std::string config_string() const = 0;
162 : };
163 :
164 :
165 : ///////////////////////////////////////////////////////////
166 : ///////////////////////////////////////////////////////////
167 : // Standard convergence check
168 : ///////////////////////////////////////////////////////////
169 : ///////////////////////////////////////////////////////////
170 :
171 : /** StdConvCheck
172 : *
173 : * This is a standard implementation of the convergence check.
174 : * The function_type must provide the following function:
175 : * - number norm() --- giving the two norm of the function
176 : */
177 : template <typename TVector>
178 : class StdConvCheck : public IConvergenceCheck<TVector>
179 : {
180 : public:
181 : StdConvCheck();
182 :
183 : StdConvCheck(int maxSteps, number minDefect, number relReduction);
184 : StdConvCheck(int maxSteps, number minDefect, number relReduction, bool verbose);
185 : StdConvCheck(int maxSteps, number minDefect, number relReduction, bool verbose,bool suppressUnsuccessful);
186 :
187 0 : void set_verbose(bool level) {m_verbose = level;}
188 0 : void set_maximum_steps(int maxSteps) {m_maxSteps = maxSteps;}
189 0 : void set_minimum_defect(number minDefect) {m_minDefect = minDefect;}
190 0 : void set_reduction(number relReduction) {m_relReduction = relReduction;}
191 0 : void set_supress_unsuccessful(bool bsupress){ m_supress_unsuccessful = bsupress; }
192 :
193 : void start_defect(number initialDefect);
194 :
195 : void start(const TVector& d);
196 :
197 : void update_defect(number newDefect);
198 :
199 : void update(const TVector& d);
200 :
201 : bool iteration_ended();
202 :
203 : bool post();
204 :
205 0 : virtual std::string config_string() const
206 : {
207 0 : std::stringstream ss;
208 0 : ss << "StdConvCheck( max steps = " << m_maxSteps << ", min defect = " << m_minDefect << ", relative reduction = " << m_relReduction << ")";
209 0 : return ss.str();
210 0 : }
211 :
212 0 : number reduction() const {return m_currentDefect/m_initialDefect;};
213 0 : number defect() const {return m_currentDefect;};
214 0 : number previous_defect() const { return m_lastDefect; }
215 0 : int step() const {return m_currentStep;}
216 0 : number rate() const {return m_currentDefect/m_lastDefect;};
217 0 : number avg_rate() const {return std::pow((number)m_ratesProduct,(number)1.0/step());}
218 :
219 0 : int get_offset() const {return m_offset;}
220 0 : void set_offset(int offset){m_offset = offset;}
221 0 : void set_symbol(char symbol){m_symbol = symbol;}
222 0 : void set_name(std::string name) {m_name = name;}
223 0 : void set_info(std::string info) {m_info = info;}
224 : const std::vector<number> get_defects() const { return _defects;}
225 0 : number get_defect(size_t i) const { return _defects[i];}
226 : void print_line(std::string line);
227 :
228 0 : virtual SmartPtr<IConvergenceCheck<TVector> > clone()
229 : {
230 0 : SmartPtr<StdConvCheck<TVector> > newInst(new StdConvCheck<TVector>);
231 : // use std assignment (implicit member-wise is fine here)
232 0 : *newInst = *this;
233 0 : return newInst;
234 : }
235 :
236 : protected:
237 : void print_offset();
238 :
239 : bool is_valid_number(number value);
240 :
241 : protected:
242 : // start defect
243 : number m_initialDefect;
244 :
245 : // current defect
246 : number m_currentDefect;
247 :
248 : // defect of the previous step
249 : number m_lastDefect;
250 :
251 : // current step
252 : int m_currentStep;
253 :
254 : // sum of the convergence rates over all steps
255 : number m_ratesProduct;
256 :
257 : protected:
258 : // maximum number of steps to be performed
259 : int m_maxSteps;
260 :
261 : // absolute reduction to be reached for convergence
262 : number m_minDefect;
263 :
264 : // relative reduction to be reached for convergence
265 : number m_relReduction;
266 :
267 : // verbose level
268 : bool m_verbose;
269 :
270 : // number of spaces inserted before output
271 : int m_offset;
272 :
273 : // symbol for output appearance
274 : char m_symbol;
275 :
276 : // name of iteration
277 : std::string m_name;
278 :
279 : // info for iteration (e.g. preconditioner type)
280 : std::string m_info;
281 :
282 : // return true in post method if max nr of iterations is reached
283 : bool m_supress_unsuccessful;
284 :
285 : private:
286 : std::vector<number> _defects;
287 : };
288 :
289 : } // end namespace ug
290 :
291 : #include "convergence_check_impl.h"
292 :
293 : #endif /* __H__LIB_ALGEBRA__OPERATOR__CONVERGENCE_CHECK__ */
|