Loading [MathJax]/extensions/tex2jax.js
ug4
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
cg.h
Go to the documentation of this file.
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#ifndef __H__UG__LIB_DISC__OPERATOR__LINEAR_SOLVER__CG__
34#define __H__UG__LIB_DISC__OPERATOR__LINEAR_SOLVER__CG__
35
36#include <iostream>
37#include <string>
38
43#ifdef UG_PARALLEL
45#endif
46
47namespace ug{
48
50
64template <typename TVector>
65class CG
67{
68 public:
70 typedef TVector vector_type;
71
74
75 protected:
80
81 public:
83 CG() : base_type() {}
84
87
89 : base_type ( spPrecond, spConvCheck) {}
90
92 virtual const char* name() const {return "CG";}
93
95 virtual bool supports_parallel() const
96 {
97 if(preconditioner().valid())
98 return preconditioner()->supports_parallel();
99 return true;
100 }
101
104 {
105 PROFILE_BEGIN_GROUP(CG_apply_return_defect, "CG algebra");
106 // check parallel storage types
107 #ifdef UG_PARALLEL
108 if(!b.has_storage_type(PST_ADDITIVE) || !x.has_storage_type(PST_CONSISTENT))
109 UG_THROW("CG::apply_return_defect:"
110 "Inadequate storage format of Vectors.");
111 #endif
112
113 // rename r as b (for convenience)
114 vector_type& r = b;
115
116 // Build defect: r := b - J(u)*x
117 linear_operator()->apply_sub(r, x);
118
119 // create help vector (h will be consistent r)
120 SmartPtr<vector_type> spQ = r.clone_without_values(); vector_type& q = *spQ;
121 SmartPtr<vector_type> spZ = x.clone_without_values(); vector_type& z = *spZ;
122 SmartPtr<vector_type> spP = x.clone_without_values(); vector_type& p = *spP;
123
125
126 // Preconditioning
127 if(preconditioner().valid())
128 {
130 // apply z = M^-1 * s
131 if(!preconditioner()->apply(z, r))
132 {
133 UG_LOG("ERROR in 'CG::apply_return_defect': "
134 "Cannot apply preconditioner. Aborting.\n");
136 return false;
137 }
139 }
140 else z = r;
141
142 // make z consistent
143 #ifdef UG_PARALLEL
144 if(!z.change_storage_type(PST_CONSISTENT))
145 UG_THROW("CG::apply_return_defect: "
146 "Cannot convert z to consistent vector.");
147 #endif
148
149 // post-process the correction
151
152 // compute start defect
154 convergence_check()->start(r);
155
156 // start search direction
157 p = z;
158
159 // start rho
160 number rhoOld = VecProd(z, r), rho;
161
162 // Iteration loop
163 while(!convergence_check()->iteration_ended())
164 {
165 // Build q = A*p (q is additive afterwards)
166 linear_operator()->apply(q, p);
167
168 // lambda = (q,p)
169 number lambda = VecProd(q, p);
170
171 // check lambda
172 if(lambda == 0.0)
173 {
174 if (p.size())
175 {
176 UG_LOG("ERROR in 'CG::apply_return_defect': lambda=" <<
177 lambda<< " is not admitted. Aborting solver.\n");
178 return false;
179 }
180 // in cases where a proc has no geometry, we do not want to fail here
181 // so we set lambda = 1, this is not harmful
182 else
183 lambda = 1.0;
184 }
185
186 // alpha = rho / (q,p)
187 const number alpha = rhoOld/lambda;
188
189 // Update x := x + alpha*p
190 VecScaleAdd(x, 1.0, x, alpha, p);
191
192 // Update r := r - alpha*t
193 VecScaleAdd(r, 1.0, r, -alpha, q);
194
196
197 // Check convergence
198 convergence_check()->update(r);
199 if(convergence_check()->iteration_ended()) break;
200
201 // Preconditioning
202 if(preconditioner().valid())
203 {
205 // apply z = M^-1 * r
206 if(!preconditioner()->apply(z, r))
207 {
208 UG_LOG("ERROR in 'CG::apply_return_defect': "
209 "Cannot apply preconditioner. Aborting.\n");
211 return false;
212 }
214 }
215 else z = r;
216
217 #ifdef UG_PARALLEL
218 // make z consistent
219 if(!z.change_storage_type(PST_CONSISTENT))
220 UG_THROW("CG::apply_return_defect': "
221 "Cannot convert z to consistent vector.");
222 #endif
223
224 // post-process the correction
226
227 // new rho = (z,r)
228 rho = VecProd(z, r);
229
230 // new beta = rho / rhoOld
231 const number beta = rho/rhoOld;
232
233 // new direction p := beta * p + z
234 VecScaleAdd(p, beta, p, 1.0, z);
235
236 // remember old rho
237 rhoOld = rho;
238 }
239
240 // post output
241 return convergence_check()->post();
242 }
243
249
255
256 protected:
259 {
260 // set iteration symbol and name
261 convergence_check()->set_name(name());
262 convergence_check()->set_symbol('%');
263
264 // set preconditioner string
265 std::string s;
266 if(preconditioner().valid())
267 s = std::string(" (Precond: ") + preconditioner()->name() + ")";
268 else
269 s = " (No Preconditioner) ";
270 convergence_check()->set_info(s);
271 }
272
274 void write_debugXR(vector_type &x, vector_type &r, int loopCnt)
275 {
276 if(!this->vector_debug_writer_valid()) return;
277 char ext[20]; snprintf(ext, 20, "_iter%03d", loopCnt);
278 write_debug(r, std::string("CG_Residual") + ext + ".vec");
279 write_debug(x, std::string("CG_Solution") + ext + ".vec");
280 }
281
284 {
285 if(!this->vector_debug_writer_valid()) return;
286 char ext[20]; snprintf(ext, 20, "_iter%03d", loopCnt);
287 this->enter_vector_debug_writer_section(std::string("CG_Precond_") + ext);
288 }
289
290 protected:
292 {
293 return a.dotprod(b);
294 }
295
296 protected:
298
304};
305
306} // end namespace ug
307
308#endif /* __H__UG__LIB_DISC__OPERATOR__LINEAR_SOLVER__CG__ */
parameterString p
parameterString s
Definition smart_pointer.h:108
the CG method as a solver for linear operators
Definition cg.h:67
CG(SmartPtr< ILinearIterator< vector_type, vector_type > > spPrecond)
Definition cg.h:85
void write_debugXR(vector_type &x, vector_type &r, int loopCnt)
debugger output: solution and residual
Definition cg.h:274
void enter_precond_debug_section(int loopCnt)
debugger section for the preconditioner
Definition cg.h:283
IPreconditionedLinearOperatorInverse< vector_type > base_type
Base type.
Definition cg.h:73
void remove_postprocess_corr(SmartPtr< IPProcessVector< vector_type > > p)
removes a post-process for the iterates
Definition cg.h:251
TVector vector_type
Vector type.
Definition cg.h:70
CG(SmartPtr< ILinearIterator< vector_type, vector_type > > spPrecond, SmartPtr< IConvergenceCheck< vector_type > > spConvCheck)
Definition cg.h:88
virtual bool apply_return_defect(vector_type &x, vector_type &b)
Solve J(u)*x = b, such that x = J(u)^{-1} b.
Definition cg.h:103
void add_postprocess_corr(SmartPtr< IPProcessVector< vector_type > > p)
adds a post-process for the iterates
Definition cg.h:245
PProcessChain< vector_type > m_corr_post_process
postprocessor for the correction in the iterations
Definition cg.h:303
void prepare_conv_check()
adjust output of convergence check
Definition cg.h:258
virtual bool supports_parallel() const
returns if parallel solving is supported
Definition cg.h:95
CG()
constructors
Definition cg.h:83
number VecProd(vector_type &a, vector_type &b)
Definition cg.h:291
virtual const char * name() const
name of solver
Definition cg.h:92
Definition convergence_check.h:72
describes a linear iterator
Definition linear_iterator.h:81
ConstSmartPtr< IConvergenceCheck< X > > convergence_check() const
returns the convergence check
Definition linear_operator_inverse.h:202
int step() const
returns the current number of steps
Definition linear_operator_inverse.h:211
SmartPtr< ILinearOperator< Y, X > > linear_operator()
returns the current Operator this Inverse Operator is initialized for
Definition linear_operator_inverse.h:227
interface for pre- and postprocess functions
Definition pprocess.h:59
describes an inverse linear mapping X->X
Definition preconditioned_linear_operator_inverse.h:63
SmartPtr< ILinearIterator< vector_type, vector_type > > preconditioner()
Definition preconditioned_linear_operator_inverse.h:118
virtual bool apply(TVector &x, const TVector &b)
Definition preconditioned_linear_operator_inverse.h:152
a chain of pre- or postprocess operations
Definition pprocess.h:78
void add(SmartPtr< p_process_type > p)
adds an operation at the end of the chain
Definition pprocess.h:96
void apply(vector_type &v)
performs all the operations
Definition pprocess.h:86
void remove(SmartPtr< p_process_type > p)
removes an operation from the chain
Definition pprocess.h:108
bool vector_debug_writer_valid() const
returns true if the debug writer is set
Definition debug_writer.h:290
void enter_vector_debug_writer_section(std::string secDir)
enters a debugging section
Definition debug_writer.h:331
void leave_vector_debug_writer_section()
leaves a debugging section
Definition debug_writer.h:342
void write_debug(const vector_type &vec, const char *filename)
writing debug output for a vector (if debug writer set)
Definition debug_writer.h:293
@ PST_CONSISTENT
Definition parallel_storage_type.h:68
@ PST_ADDITIVE
Definition parallel_storage_type.h:69
#define UG_THROW(msg)
Definition error.h:57
#define UG_LOG(msg)
Definition log.h:367
double number
Definition types.h:124
void VecScaleAdd(vector_t &vOut, typename vector_t::value_type s1, const vector_t &v1, typename vector_t::value_type s2, const vector_t &v2)
Scales two Vectors, adds them and returns the sum in a third vector.
Definition math_vector_functions_common_impl.hpp:265
the ug namespace
#define PROFILE_BEGIN_GROUP(name, groups)
Definition profiler.h:255