FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
pcgnrilu.hpp
1// FEAT3: Finite Element Analysis Toolbox, Version 3
2// Copyright (C) 2010 by Stefan Turek & the FEAT group
3// FEAT3 is released under the GNU General Public License version 3,
4// see the file 'copyright.txt' in the top level directory for details.
5
6#pragma once
7
8// includes, FEAT
9#include <kernel/solver/iterative.hpp>
10#include <kernel/solver/ilu_precond.hpp>
11
12namespace FEAT
13{
14 namespace Solver
15 {
42 template<
43 typename Matrix_,
44 typename Filter_>
45 class PCGNRILU :
46 public IterativeSolver<typename Matrix_::VectorTypeR>
47 {
48 public:
49 typedef Matrix_ MatrixType;
50 typedef Filter_ FilterType;
51 typedef typename MatrixType::VectorTypeR VectorType;
52 typedef typename MatrixType::DataType DataType;
53 typedef typename MatrixType::IndexType IndexType;
55
56 protected:
58 const MatrixType& _system_matrix;
60 const FilterType& _system_filter;
62 MatrixType _transp_matrix;
64 VectorType _vec_r, _vec_p, _vec_q, _vec_s, _vec_t;
66 int _ilu_p;
68 Intern::ILUCoreScalar<DataType, IndexType> _ilu;
69
70 public:
83 explicit PCGNRILU(const MatrixType& matrix, const FilterType& filter, int ilu_p = -1) :
84 BaseClass("PCGNRILU"),
85 _system_matrix(matrix),
86 _system_filter(filter),
87 _ilu_p(ilu_p)
88 {
89 // set communicator by system matrix
90 this->_set_comm_by_matrix(matrix);
91 }
92
109 explicit PCGNRILU(const String& section_name, const PropertyMap* section,
110 const MatrixType& matrix, const FilterType& filter) :
111 BaseClass("PCGNRILU", section_name, section),
112 _system_matrix(matrix),
113 _system_filter(filter),
114 _ilu_p(-1)
115 {
116 // set communicator by system matrix
117 this->_set_comm_by_matrix(matrix);
118
119 auto fill_in_param_p = section->query("fill_in_param");
120 if(fill_in_param_p.second && !fill_in_param_p.first.parse(_ilu_p))
121 throw ParseError(section_name + ".fill_in_param", fill_in_param_p.first, "a non-negative integer");
122 }
123
127 virtual ~PCGNRILU()
128 {
129 }
130
138 {
139 XASSERT(p >= -1);
140 _ilu_p = p;
141 }
142
143 virtual String name() const override
144 {
145 return "PCGNRILU";
146 }
147
148 virtual void init_symbolic() override
149 {
151
152 _vec_p = this->_system_matrix.create_vector_r();
153 _vec_q = this->_system_matrix.create_vector_r();
154 _vec_r = this->_system_matrix.create_vector_r();
155 _vec_s = this->_system_matrix.create_vector_r();
156 _vec_t = this->_system_matrix.create_vector_r();
157
158 if(_ilu_p >= 0)
159 {
160 _ilu.set_struct(this->_system_matrix);
161 _ilu.factorize_symbolic(_ilu_p);
162 _ilu.alloc_data();
163 }
164 }
165
166 virtual void done_symbolic() override
167 {
168 _ilu.clear();
169
170 this->_vec_t.clear();
171 this->_vec_s.clear();
172 this->_vec_r.clear();
173 this->_vec_q.clear();
174 this->_vec_p.clear();
175
177 }
178
179 virtual void init_numeric() override
180 {
182
184 if(_ilu_p >= 0)
185 {
186 _ilu.copy_data(_system_matrix);
187 _ilu.factorize_numeric_il_du();
188 }
189 }
190
191 virtual Status apply(VectorType& vec_cor, const VectorType& vec_def) override
192 {
193 // save defect
194 this->_vec_r.copy(vec_def);
195
196 // clear solution vector
197 vec_cor.format();
198
199 // apply solver
200 this->_status = _apply_intern(vec_cor);
201
202 // plot summary
203 this->plot_summary();
204
205 // return status
206 return this->_status;
207 }
208
209 virtual Status correct(VectorType& vec_sol, const VectorType& vec_rhs) override
210 {
211 // compute defect
212 this->_system_matrix.apply(this->_vec_r, vec_sol, vec_rhs, -DataType(1));
213 this->_system_filter.filter_def(this->_vec_r);
214
215 // apply solver
216 this->_status = _apply_intern(vec_sol);
217
218 // plot summary
219 this->plot_summary();
220
221 // return status
222 return this->_status;
223 }
224
225 protected:
226 void _precond_l(VectorType& vec_c, const VectorType& vec_q)
227 {
228 vec_c.copy(vec_q);
229 if(_ilu_p >= 0)
230 {
231 DataType* x = vec_c.elements();
232 _ilu.solve_il(x, x);
233 _ilu.solve_ilt(x, x);
234 }
235 }
236
237 void _precond_r(VectorType& vec_c, const VectorType& vec_q)
238 {
239 vec_c.copy(vec_q);
240 if(_ilu_p >= 0)
241 {
242 DataType* x = vec_c.elements();
243 _ilu.solve_dut(x, x);
244 _ilu.solve_du(x, x);
245 }
246 }
247
248 virtual Status _apply_intern(VectorType& vec_x)
249 {
250 Statistics::add_solver_expression(std::make_shared<ExpressionStartSolve>(this->name()));
251
252 const MatrixType& matrix(this->_system_matrix);
253 const MatrixType& transp(this->_transp_matrix);
254 const FilterType& filter(this->_system_filter);
255
256 VectorType& vec_p(this->_vec_p);
257 VectorType& vec_q(this->_vec_q);
258 VectorType& vec_r(this->_vec_r);
259 VectorType& vec_s(this->_vec_s);
260 VectorType& vec_t(this->_vec_t);
261 VectorType& vec_y(this->_vec_s); // same as s
262 VectorType& vec_z(this->_vec_t); // same as t
263
264 // compute initial defect:
265 // r[0] := b - A*x[0]
266 Status status = this->_set_initial_defect(vec_r, vec_x);
267 if(status != Status::progress)
268 {
269 Statistics::add_solver_expression(std::make_shared<ExpressionEndSolve>(this->name(), status, this->get_num_iter()));
270 return status;
271 }
272
273 // apply left preconditioner to defect vector
274 // p[0] := (L*L^T)^{-1} r[0]
275 this->_precond_l(vec_p, vec_r);
276 filter.filter_cor(vec_p);
277
278 // apply transposed matrix
279 // s[0] := A^T * p[0]
280 transp.apply(vec_s, vec_p);
281 filter.filter_def(vec_s);
282
283 // apply right preconditioner
284 // q[0] := (R^T*R)^{-1} * s[0]
285 this->_precond_r(vec_q, vec_s);
286 filter.filter_cor(vec_q);
287
288 // compute initial gamma:
289 // gamma[0] := < s[0], q[0] >
290 DataType gamma = vec_s.dot(vec_q);
291
292 // start iterating
293 while(status == Status::progress)
294 {
295 IterationStats stat(*this);
296
297 // y[k] := A * q[k]
298 matrix.apply(vec_y, vec_q);
299 filter.filter_def(vec_y);
300
301 // z[k] := (L*L^T)^{-1} * y[k]
302 this->_precond_l(vec_z, vec_y);
303 filter.filter_cor(vec_z);
304
305 // compute alpha
306 // alpha[k] := gamma[k] / < y[k], z[k] >
307 DataType alpha = gamma / vec_y.dot(vec_z);
308
309 // update solution vector
310 // x[k+1] := x[k] + alpha[k] * q[k]
311 vec_x.axpy(vec_q, alpha);
312
313 // update defect vector
314 // r[k+1] := r[k] - alpha[k] * y[k]
315 vec_r.axpy(vec_y, -alpha);
316
317 // compute defect norm
318 status = this->_set_new_defect(vec_r, vec_x);
319 if(status != Status::progress)
320 {
321 Statistics::add_solver_expression(std::make_shared<ExpressionEndSolve>(this->name(), status, this->get_num_iter()));
322 return status;
323 }
324
325 // p[k+1] := p[k] - alpha[k] * z[k]
326 vec_p.axpy(vec_z, -alpha);
327
328 // s[k+1] := A^T * p[k+1]
329 transp.apply(vec_s, vec_p);
330 filter.filter_def(vec_s);
331
332 // t[k+1] := (R^T*R)^{-1} * s[k+1]
333 this->_precond_r(vec_t, vec_s);
334 filter.filter_cor(vec_t);
335
336 // compute new gamma
337 // gamma[k+1] := < s[k+1], t[k+1] >
338 DataType gamma2 = gamma;
339 gamma = vec_s.dot(vec_t);
340
341 // compute beta
342 // beta[k] := gamma[k+1] / gamma[k]
343 DataType beta = gamma / gamma2;
344
345 // update direction vector
346 // q[k+1] := t[k+1] + beta * q[k]
347 vec_q.scale(vec_q, beta);
348 vec_q.axpy(vec_t);
349 }
350
351 // we should never reach this point...
352 Statistics::add_solver_expression(std::make_shared<ExpressionEndSolve>(this->name(), Status::undefined, this->get_num_iter()));
353 return Status::undefined;
354 }
355 }; // class PCGNRILU<...>
356
372 template<typename Matrix_, typename Filter_>
373 inline std::shared_ptr<PCGNRILU<Matrix_, Filter_>> new_pcgnrilu(
374 const Matrix_& matrix, const Filter_& filter, int ilu_p = -1)
375 {
376 return std::make_shared<PCGNRILU<Matrix_, Filter_>>(matrix, filter, ilu_p);
377 }
378
397 template<typename Matrix_, typename Filter_>
398 inline std::shared_ptr<PCGNRILU<Matrix_, Filter_>> new_pcgnrilu(
399 const String& section_name, const PropertyMap* section,
400 const Matrix_& matrix, const Filter_& filter)
401 {
402 return std::make_shared<PCGNRILU<Matrix_, Filter_>>(section_name, section, matrix, filter);
403 }
404 } // namespace Solver
405} // namespace FEAT
#define XASSERT(expr)
Assertion macro definition.
Definition: assertion.hpp:262
Class for parser related errors.
Definition: exception.hpp:132
A class organizing a tree of key-value pairs.
std::pair< String, bool > query(String key_path) const
Queries a value by its key path.
Helper class for iteration statistics collection.
Definition: base.hpp:392
Abstract base-class for iterative solvers.
Definition: iterative.hpp:198
Index get_num_iter() const
Returns number of performed iterations.
Definition: iterative.hpp:462
Status _status
current status of the solver
Definition: iterative.hpp:213
void _set_comm_by_matrix(const Matrix_ &matrix)
Sets the communicator for the solver from a matrix.
Definition: iterative.hpp:680
virtual Status _set_new_defect(const VectorType &vec_def, const VectorType &vec_sol)
Internal function: sets the new (next) defect vector.
Definition: iterative.hpp:924
virtual void plot_summary() const
Plot a summary of the last solver run.
Definition: iterative.hpp:627
virtual Status _set_initial_defect(const VectorType &vec_def, const VectorType &vec_sol)
Internal function: sets the initial defect vector.
Definition: iterative.hpp:802
ILU(p)-preconditioned Conjugate-Gradient on Normal Equations solver implementation.
Definition: pcgnrilu.hpp:47
PCGNRILU(const String &section_name, const PropertyMap *section, const MatrixType &matrix, const FilterType &filter)
Constructor using a PropertyMap.
Definition: pcgnrilu.hpp:109
VectorType _vec_r
temporary vectors
Definition: pcgnrilu.hpp:64
MatrixType _transp_matrix
the transposed system matrix
Definition: pcgnrilu.hpp:62
const FilterType & _system_filter
the filter for the solver
Definition: pcgnrilu.hpp:60
int _ilu_p
ilu fill-in
Definition: pcgnrilu.hpp:66
Intern::ILUCoreScalar< DataType, IndexType > _ilu
ilu factorization data
Definition: pcgnrilu.hpp:68
void set_fill_in_param(int p)
Sets the fill-in parameter.
Definition: pcgnrilu.hpp:137
const MatrixType & _system_matrix
the matrix for the solver
Definition: pcgnrilu.hpp:58
virtual void init_symbolic() override
Symbolic initialization method.
Definition: pcgnrilu.hpp:148
virtual String name() const override
Returns a descriptive string.
Definition: pcgnrilu.hpp:143
virtual Status _apply_intern(VectorType &vec_x)
Definition: pcgnrilu.hpp:248
virtual void done_symbolic() override
Symbolic finalization method.
Definition: pcgnrilu.hpp:166
PCGNRILU(const MatrixType &matrix, const FilterType &filter, int ilu_p=-1)
Constructor.
Definition: pcgnrilu.hpp:83
virtual ~PCGNRILU()
Empty virtual destructor.
Definition: pcgnrilu.hpp:127
virtual void init_numeric() override
Numeric initialization method.
Definition: pcgnrilu.hpp:179
virtual void init_symbolic()
Symbolic initialization method.
Definition: base.hpp:227
virtual void init_numeric()
Numeric initialization method.
Definition: base.hpp:237
virtual void done_symbolic()
Symbolic finalization method.
Definition: base.hpp:255
String class implementation.
Definition: string.hpp:46
Status
Solver status return codes enumeration.
Definition: base.hpp:47
@ progress
continue iteration (internal use only)
@ undefined
undefined status
std::shared_ptr< PCGNRILU< Matrix_, Filter_ > > new_pcgnrilu(const Matrix_ &matrix, const Filter_ &filter, int ilu_p=-1)
Creates a new PCGNRILU solver object.
Definition: pcgnrilu.hpp:373
FEAT namespace.
Definition: adjactor.hpp:12