FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
rbicgstab.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
11namespace FEAT
12{
13 namespace Solver
14 {
31 template<typename Matrix_, typename Filter_>
32 class RBiCGStab :
33 public PreconditionedIterativeSolver<typename Matrix_::VectorTypeR>
34 {
35 public:
37 typedef Matrix_ MatrixType;
39 typedef Filter_ FilterType;
41 typedef typename MatrixType::VectorTypeR VectorType;
43 typedef typename MatrixType::DataType DataType;
48
49 protected:
55 VectorType _vec_v, _vec_vh, _vec_z, _vec_s, _vec_t, _vec_th, _vec_r, _vec_r0;
56
57 public:
70 explicit RBiCGStab(const MatrixType& matrix, const FilterType& filter,
71 std::shared_ptr<PrecondType> precond = nullptr) :
72 BaseClass("RBiCGStab", precond),
73 _system_matrix(matrix),
74 _system_filter(filter)
75 {
76 // we always need to compute defect norms
77 this->_force_def_norm_calc = true;
78
79 // set communicator by system matrix
80 this->_set_comm_by_matrix(matrix);
81 }
82
102 explicit RBiCGStab(const String& section_name, const PropertyMap* section,
103 const MatrixType& matrix, const FilterType& filter,
104 std::shared_ptr<PrecondType> precond = nullptr) :
105 BaseClass("RBiCGStab", section_name, section, precond),
106 _system_matrix(matrix),
107 _system_filter(filter)
108 {
109 // we always need to compute defect norms
110 this->_force_def_norm_calc = true;
111
112 // set communicator by system matrix
113 this->_set_comm_by_matrix(matrix);
114 }
115
117 virtual String name() const override
118 {
119 return "RBiCGStab";
120 }
121
128 virtual void force_defect_norm_calc(bool DOXY(force)) override
129 {
130 // force is already applied in constructor
131 }
132
134 virtual void init_symbolic() override
135 {
137 // create fife temporary vectors
138 _vec_v = this->_system_matrix.create_vector_r();
139 _vec_vh = this->_system_matrix.create_vector_r();
140 _vec_z = this->_system_matrix.create_vector_r();
141 _vec_s = this->_system_matrix.create_vector_r();
142 _vec_t = this->_system_matrix.create_vector_r();
143 _vec_th = this->_system_matrix.create_vector_r();
144 _vec_r = this->_system_matrix.create_vector_r();
145 _vec_r0 = this->_system_matrix.create_vector_r();
146
147 }
148
150 virtual void done_symbolic() override
151 {
152 this->_vec_v.clear();
153 this->_vec_vh.clear();
154 this->_vec_z.clear();
155 this->_vec_s.clear();
156 this->_vec_t.clear();
157 this->_vec_th.clear();
158 this->_vec_r.clear();
159 this->_vec_r0.clear();
161 }
162
164 virtual Status apply(VectorType& vec_cor, const VectorType& vec_def) override
165 {
166 // save defect
167 this->_vec_r.copy(vec_def);
168
169 // clear solution vector
170 vec_cor.format();
171
172 // apply solver
173 this->_status = _apply_intern(vec_cor);
174
175 // plot summary
176 this->plot_summary();
177
178 // return status
179 return this->_status;
180 }
181
183 virtual Status correct(VectorType& vec_sol, const VectorType& vec_rhs) override
184 {
185 // compute defect
186 this->_system_matrix.apply(this->_vec_r, vec_sol, vec_rhs, -DataType(1));
187 this->_system_filter.filter_def(this->_vec_r);
188
189 // apply solver
190 this->_status = _apply_intern(vec_sol);
191
192 // plot summary
193 this->plot_summary();
194
195 // return status
196 return this->_status;
197 }
198
199 protected:
213 {
214 IterationStats pre_iter(*this);
215 Statistics::add_solver_expression(std::make_shared<ExpressionStartSolve>(this->name()));
216
217 const MatrixType& matrix(this->_system_matrix);
218 const FilterType& filter(this->_system_filter);
219 VectorType& vec_v(this->_vec_v);
220 VectorType& vec_vh(this->_vec_vh);
221 VectorType& vec_z(this->_vec_z);
222 VectorType& vec_s(this->_vec_s);
223 VectorType& vec_t(this->_vec_t);
224 VectorType& vec_th(this->_vec_th);
225 VectorType& vec_r(this->_vec_r);
226 VectorType& vec_r0(this->_vec_r0);
227
228 DataType rho(0);
229 DataType rho_old(0);
230 DataType delta(0);
231 DataType alpha(0);
232 DataType theta(0);
233 DataType omega(0);
234 DataType beta(0);
235 DataType phi(0);
236 DataType psi(0);
237
238 vec_r0.copy(vec_r);
239
240 // set initial defect:
241 // r[0] := b - A*x[0]
242 Status status = this->_set_initial_defect(vec_r, vec_sol);
243 if(status != Status::progress)
244 {
245 pre_iter.destroy();
246 Statistics::add_solver_expression(std::make_shared<ExpressionEndSolve>(this->name(), status, this->get_num_iter()));
247 return status;
248 }
249
250 auto dot_rho = vec_r.dot_async(vec_r);
251
252 // apply preconditioner to defect vector
253 if(!this->_apply_precond(vec_z, vec_r, filter))
254 {
255 pre_iter.destroy();
256 Statistics::add_solver_expression(std::make_shared<ExpressionEndSolve>(this->name(), Status::aborted, this->get_num_iter()));
257 return Status::aborted;
258 }
259
260 vec_vh.copy(vec_z);
261
262 rho = dot_rho.wait();
263 rho_old = rho;
264
265 pre_iter.destroy();
266
267 // start iterating
268 while(status == Status::progress)
269 {
270 IterationStats stat(*this);
271
272 matrix.apply(vec_v, vec_vh);
273 filter.filter_def(vec_v);
274
275 auto dot_delta = vec_v.dot_async(vec_r0);
276
277 // apply preconditioner
278 if(!this->_apply_precond(vec_s, vec_v, filter))
279 {
280 stat.destroy();
281 Statistics::add_solver_expression(std::make_shared<ExpressionEndSolve>(this->name(), Status::aborted, this->get_num_iter()));
282 return Status::aborted;
283 }
284
285 delta = dot_delta.wait();
286 alpha = rho / delta;
287
288 vec_th.copy(vec_z);
289 vec_th.axpy(vec_s, -alpha);
290
291 matrix.apply(vec_t, vec_th);
292 filter.filter_def(vec_t);
293
294 vec_sol.axpy(vec_vh, alpha);
295 vec_r.axpy(vec_v, -alpha);
296 auto norm_def_half = vec_r.norm2_async();
297
298 auto dot_theta = vec_t.dot_async(vec_r);
299 auto dot_phi = vec_t.dot_async(vec_t);
300 auto dot_psi = vec_t.dot_async(vec_r0);
301
302 // apply preconditioner
303 if(!this->_apply_precond(vec_z, vec_t, filter))
304 {
305 stat.destroy();
306 Statistics::add_solver_expression(std::make_shared<ExpressionEndSolve>(this->name(), Status::aborted, this->get_num_iter()));
307 return Status::aborted;
308 }
309
310 theta = dot_theta.wait();
311 phi = dot_phi.wait();
312 psi = dot_psi.wait();
313
314 // Check if we are already converged or failed after the "half" update
315 {
316 Status status_half(Status::progress);
317
318 DataType def_old(this->_def_cur);
319 DataType def_half(norm_def_half.wait());
320
321 // ensure that the defect is neither NaN nor infinity
322 if(!Math::isfinite(def_half))
323 {
324 status_half = Status::aborted;
325 }
326 // is diverged?
327 else if(this->is_diverged(def_half))
328 {
329 this->_def_cur = def_half;
330 status_half = Status::diverged;
331 }
332 // is converged?
333 else if(this->is_converged(def_half))
334 {
335 this->_def_cur = def_half;
336 status_half = Status::success;
337 }
338
339 // If we break early, we still count this iteration and plot it if necessary
340 if(status_half != Status::progress)
341 {
342 ++this->_num_iter;
343 this->_def_prev = def_old;
344 // plot?
345 if(this->_plot_iter())
346 this->_plot_iter_line(this->_num_iter, this->_def_cur, def_old);
347
348 stat.destroy();
349 Statistics::add_solver_expression(
350 std::make_shared<ExpressionEndSolve>(this->name(), status_half, this->get_num_iter()));
351
352 return status_half;
353 }
354 }
355
356 omega = theta / phi;
357
358 vec_sol.axpy(vec_th, omega);
359 vec_r.axpy(vec_t, -omega);
360
361 auto norm_def_cur = vec_r.norm2_async();
362
363 rho = -omega * psi;
364 vec_z.scale(vec_z, -omega);
365 vec_z.axpy(vec_th);
366 beta = (rho / rho_old) * (alpha / omega);
367 rho_old = rho;
368 vec_vh.axpy(vec_s, -omega);
369 vec_vh.scale(vec_vh, beta);
370 vec_vh.axpy(vec_z);
371
372 status = this->_update_defect(norm_def_cur.wait());
373 if(status != Status::progress)
374 {
375 stat.destroy();
376 Statistics::add_solver_expression(std::make_shared<ExpressionEndSolve>(this->name(), status, this->get_num_iter()));
377 return status;
378 }
379 }
380
381 // we should never reach this point...
382 Statistics::add_solver_expression(std::make_shared<ExpressionEndSolve>(this->name(), Status::undefined, this->get_num_iter()));
383 return Status::undefined;
384 }
385 }; // class RBiCGStab<...>
386
402 template<typename Matrix_, typename Filter_>
403 inline std::shared_ptr<RBiCGStab<Matrix_, Filter_>> new_rbicgstab(
404 const Matrix_& matrix, const Filter_& filter,
405 std::shared_ptr<SolverBase<typename Matrix_::VectorTypeL>> precond = nullptr)
406 {
407 return std::make_shared<RBiCGStab<Matrix_, Filter_>>(matrix, filter, precond);
408 }
409
431 template<typename Matrix_, typename Filter_>
432 inline std::shared_ptr<RBiCGStab<Matrix_, Filter_>> new_rbicgstab(
433 const String& section_name, const PropertyMap* section,
434 const Matrix_& matrix, const Filter_& filter,
435 std::shared_ptr<SolverBase<typename Matrix_::VectorTypeL>> precond = nullptr)
436 {
437 return std::make_shared<RBiCGStab<Matrix_, Filter_>>(section_name, section, matrix, filter, precond);
438 }
439 } // namespace Solver
440} // namespace FEAT
A class organizing a tree of key-value pairs.
Helper class for iteration statistics collection.
Definition: base.hpp:392
void destroy()
destroy the objects contents (and generate Statistics::expression) before the actual destructor call
Definition: base.hpp:464
bool _force_def_norm_calc
whether skipping of defect computation is allowed or not
Definition: iterative.hpp:249
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
bool is_diverged() const
checks for divergence
Definition: iterative.hpp:552
DataType _def_prev
previous iteration defect
Definition: iterative.hpp:241
virtual void _plot_iter_line(Index num_iter, DataType def_cur, DataType def_prev)
Plots an iteration line.
Definition: iterative.hpp:773
virtual Status _update_defect(const DataType def_cur_norm)
Internal function: sets the new (next) defect norm.
Definition: iterative.hpp:970
Index _num_iter
number of performed iterations
Definition: iterative.hpp:231
bool _plot_iter(Status st=Status::progress) const
Plot the current iteration?
Definition: iterative.hpp:720
DataType _def_cur
current defect
Definition: iterative.hpp:239
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
bool is_converged() const
checks for convergence
Definition: iterative.hpp:533
Abstract base-class for preconditioned iterative solvers.
Definition: iterative.hpp:1027
virtual void init_symbolic() override
Symbolic initialization method.
Definition: iterative.hpp:1086
bool _apply_precond(VectorType &vec_cor, const VectorType &vec_def, const Filter_ &filter)
Applies the preconditioner onto a defect vector.
Definition: iterative.hpp:1140
virtual void done_symbolic() override
Symbolic finalization method.
Definition: iterative.hpp:1110
(Preconditioned) reordered BiCGStab solver implementation
Definition: rbicgstab.hpp:34
MatrixType::VectorTypeR VectorType
The vector type this solver can be applied to.
Definition: rbicgstab.hpp:41
virtual String name() const override
Returns a descriptive string.
Definition: rbicgstab.hpp:117
PreconditionedIterativeSolver< VectorType > BaseClass
Our base class.
Definition: rbicgstab.hpp:45
SolverBase< VectorType > PrecondType
The type of the preconditioner that can be used.
Definition: rbicgstab.hpp:47
const MatrixType & _system_matrix
the matrix for the solver
Definition: rbicgstab.hpp:51
virtual Status apply(VectorType &vec_cor, const VectorType &vec_def) override
Solver application method.
Definition: rbicgstab.hpp:164
virtual Status correct(VectorType &vec_sol, const VectorType &vec_rhs) override
Solver correction method.
Definition: rbicgstab.hpp:183
const FilterType & _system_filter
the filter for the solver
Definition: rbicgstab.hpp:53
Filter_ FilterType
The filter for projecting solution, rhs, defect and correction vectors to subspaces.
Definition: rbicgstab.hpp:39
RBiCGStab(const MatrixType &matrix, const FilterType &filter, std::shared_ptr< PrecondType > precond=nullptr)
Constructor.
Definition: rbicgstab.hpp:70
virtual void init_symbolic() override
Symbolic initialization method.
Definition: rbicgstab.hpp:134
RBiCGStab(const String &section_name, const PropertyMap *section, const MatrixType &matrix, const FilterType &filter, std::shared_ptr< PrecondType > precond=nullptr)
Constructor using a PropertyMap.
Definition: rbicgstab.hpp:102
MatrixType::DataType DataType
The floating point precision.
Definition: rbicgstab.hpp:43
VectorType _vec_v
temp vectors
Definition: rbicgstab.hpp:55
Matrix_ MatrixType
The type of matrix this solver can be applied to.
Definition: rbicgstab.hpp:37
virtual void force_defect_norm_calc(bool force) override
Forces the calculation of defect norms in every iteration (overridden)
Definition: rbicgstab.hpp:128
virtual Status _apply_intern(VectorType &vec_sol)
Internal function, applies the solver.
Definition: rbicgstab.hpp:212
virtual void done_symbolic() override
Symbolic finalization method.
Definition: rbicgstab.hpp:150
Polymorphic solver interface.
Definition: base.hpp:183
String class implementation.
Definition: string.hpp:46
bool isfinite(T_ x)
Checks whether a value is finite.
std::shared_ptr< RBiCGStab< Matrix_, Filter_ > > new_rbicgstab(const Matrix_ &matrix, const Filter_ &filter, std::shared_ptr< SolverBase< typename Matrix_::VectorTypeL > > precond=nullptr)
Creates a new RBiCGStab solver object.
Definition: rbicgstab.hpp:403
Status
Solver status return codes enumeration.
Definition: base.hpp:47
@ success
solving successful (convergence criterion fulfilled)
@ progress
continue iteration (internal use only)
@ undefined
undefined status
@ diverged
solver diverged (divergence criterion fulfilled)
@ aborted
premature abort (solver aborted due to internal errors or preconditioner failure)
FEAT namespace.
Definition: adjactor.hpp:12