9#include <kernel/solver/iterative.hpp>
80 typedef Matrix_ MatrixType;
81 typedef Filter_ FilterType;
82 typedef typename MatrixType::VectorTypeR VectorType;
83 typedef typename MatrixType::DataType DataType;
101 std::vector<DataType>
_c, _s, _q;
103 std::vector<std::vector<DataType>>
_h;
124 explicit GMRES(
const MatrixType& matrix,
const FilterType& filter,
Index krylov_dim,
125 DataType inner_res_scale = DataType(0), std::shared_ptr<PrecondType> precond =
nullptr) :
140 const MatrixType& matrix,
const FilterType& filter, std::shared_ptr<PrecondType> precond =
nullptr) :
141 BaseClass(
"GMRES", section_name, section, precond),
153 auto inner_res_scale_p = section->
query(
"inner_res_scale");
154 if(inner_res_scale_p.second && (!inner_res_scale_p.first.parse(this->_inner_res_scale) || (this->_inner_res_scale < DataType(0))))
155 throw ParseError(section_name +
".inner_res_scale", inner_res_scale_p.first,
"a non-negative float");
158 auto krylov_dim_p = section->
query(
"krylov_dim");
159 if(!krylov_dim_p.second)
160 throw ParseError(
"GMRES config section is missing the mandatory krylov_dim!");
162 if(!krylov_dim_p.first.parse(this->_krylov_dim) || (this->_krylov_dim <=
Index(0)))
163 throw ParseError(section_name +
".krylov_dim", krylov_dim_p.first,
"a positive integer");
203 _h.at(i).resize(i+1);
206 _vec_v.push_back(this->_system_matrix.create_vector_r());
207 _vec_w = this->_system_matrix.create_vector_r();
242 XASSERT(inner_res_scale >= DataType(0));
247 virtual Status apply(VectorType& vec_sol,
const VectorType& vec_rhs)
override
252 this->_vec_v.at(0).copy(vec_rhs);
258 this->
_status = _apply_intern(vec_sol, vec_rhs);
264 virtual Status correct(VectorType& vec_sol,
const VectorType& vec_rhs)
override
267 this->_system_matrix.apply(this->_vec_v.at(0), vec_sol, vec_rhs, -DataType(1));
268 this->_system_filter.filter_def(this->_vec_v.at(0));
271 this->
_status = _apply_intern(vec_sol, vec_rhs);
277 virtual Status _apply_intern(VectorType& vec_sol,
const VectorType& vec_rhs)
280 Statistics::add_solver_expression(std::make_shared<ExpressionStartSolve>(this->
name()));
281 const MatrixType& matrix(this->_system_matrix);
282 const FilterType& filter(this->_system_filter);
300 this->_vec_v.at(0).scale(this->_vec_v.at(0), DataType(1) / _q.back());
307 if(!this->
_apply_precond(this->_vec_w, this->_vec_v.at(i), filter))
316 matrix.apply(this->_vec_v.at(i+1), this->_vec_w);
317 filter.filter_def(this->_vec_v.at(i+1));
320 for(
Index k(0); k <= i; ++k)
322 this->_h.at(i).at(k) = this->_vec_v.at(i+1).dot(this->_vec_v.at(k));
323 this->_vec_v.at(i+1).axpy(this->_vec_v.at(k), -this->_h.at(i).at(k));
327 DataType alpha = this->_vec_v.at(i+1).norm2();
328 this->_vec_v.at(i+1).scale(this->_vec_v.at(i+1), DataType(1) / alpha);
331 for(
Index k(0); k < i; ++k)
333 DataType t(this->_h.at(i).at(k));
334 this->_h.at(i).at(k ) = this->_c.at(k) * t + this->_s.at(k) * this->_h.at(i).at(k+1);
335 this->_h.at(i).at(k+1) = this->_s.at(k) * t - this->_c.at(k) * this->_h.at(i).at(k+1);
342 _s.push_back(alpha / beta);
343 _c.push_back(this->_h.at(i).at(i) / beta);
345 this->_h.at(i).at(i) = beta;
346 this->_q.push_back(this->_s.back() * this->_q.at(i));
347 this->_q.at(i) *= this->_c.back();
353 DataType def_cur =
Math::abs(this->_q.back());
363 if((def_cur <= _inner_res_scale * this->
_tol_abs) &&
404 for(
Index k(n); k > 0;)
407 this->_q.at(k) /= this->_h.at(k).at(k);
408 for(
Index j(k); j > 0;)
411 this->_q.at(j) -= this->_h.at(k).at(j) * this->_q.at(k);
416 this->_vec_w.format();
417 for(
Index k(0); k < n; ++k)
418 this->_vec_w.axpy(this->_vec_v.at(k), this->_q.at(k));
421 if(!this->
_apply_precond(this->_vec_v.front(), this->_vec_w, filter))
427 vec_sol.axpy(this->_vec_v.front());
430 matrix.apply(this->_vec_v.at(0), vec_sol, vec_rhs, -DataType(1));
431 filter.filter_def(this->_vec_v.at(0));
439 Statistics::add_solver_expression(std::make_shared<ExpressionEndSolve>(this->
name(), status, this->
get_num_iter()));
466 template<
typename Matrix_,
typename Filter_>
467 inline std::shared_ptr<GMRES<Matrix_, Filter_>>
new_gmres(
468 const Matrix_& matrix,
const Filter_& filter,
Index krylov_dim,
469 typename Matrix_::DataType inner_res_scale =
typename Matrix_::DataType(0),
472 return std::make_shared<GMRES<Matrix_, Filter_>>(matrix, filter, krylov_dim, inner_res_scale, precond);
496 template<
typename Matrix_,
typename Filter_>
497 inline std::shared_ptr<GMRES<Matrix_, Filter_>>
new_gmres(
499 const Matrix_& matrix,
const Filter_& filter,
502 return std::make_shared<GMRES<Matrix_, Filter_>>(section_name, section, matrix, filter, precond);
#define XASSERT(expr)
Assertion macro definition.
Class for parser related errors.
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.
GMRES(k) solver implementation.
const FilterType & _system_filter
the filter for the solver
virtual String name() const override
Returns a descriptive string.
virtual void init_symbolic() override
Symbolic initialization method.
virtual void set_inner_res_scale(DataType inner_res_scale)
Sets the inner residual scale.
GMRES(const MatrixType &matrix, const FilterType &filter, Index krylov_dim, DataType inner_res_scale=DataType(0), std::shared_ptr< PrecondType > precond=nullptr)
Constructor.
virtual Status correct(VectorType &vec_sol, const VectorType &vec_rhs) override
DataType _inner_res_scale
inner pseudo-residual scaling factor, see the documentation of this class for details
virtual Status apply(VectorType &vec_sol, const VectorType &vec_rhs) override
Solver application method.
std::vector< VectorType > _vec_v
krylov basis vector
std::vector< std::vector< DataType > > _h
Hessenberg matrix.
virtual void set_krylov_dim(Index krylov_dim)
Sets the inner Krylov space dimension.
const MatrixType & _system_matrix
the matrix for the solver
virtual ~GMRES()
Empty virtual destructor.
virtual void done_symbolic() override
Symbolic finalization method.
std::vector< DataType > _c
Givens rotation coefficients.
virtual void force_defect_norm_calc(bool force) override
Forces the calculation of defect norms in every iteration (overridden)
Index _krylov_dim
krylov dimension
Helper class for iteration statistics collection.
bool _force_def_norm_calc
whether skipping of defect computation is allowed or not
void set_plot_name(const String &plot_name)
Sets the plot name of the solver.
DataType _def_init
initial defect
Index _min_iter
minimum number of iterations
Index _iter_digits
iteration count digits for plotting
Index get_num_iter() const
Returns number of performed iterations.
Status _status
current status of the solver
void _set_comm_by_matrix(const Matrix_ &matrix)
Sets the communicator for the solver from a matrix.
void _print_line(const String &line) const
Prints a line.
String _plot_name
name of the solver in plots
DataType _div_rel
relative divergence parameter
DataType _div_abs
absolute divergence parameter
virtual Status _set_new_defect(const VectorType &vec_def, const VectorType &vec_sol)
Internal function: sets the new (next) defect vector.
Index _num_iter
number of performed iterations
bool _plot_iter(Status st=Status::progress) const
Plot the current iteration?
DataType _tol_rel
relative tolerance parameter
DataType _def_cur
current defect
virtual void plot_summary() const
Plot a summary of the last solver run.
Index _max_iter
maximum number of iterations
DataType _tol_abs_low
absolute low tolerance parameter
virtual Status _set_initial_defect(const VectorType &vec_def, const VectorType &vec_sol)
Internal function: sets the initial defect vector.
DataType _tol_abs
absolute tolerance parameter
Abstract base-class for preconditioned iterative solvers.
virtual void init_symbolic() override
Symbolic initialization method.
bool _apply_precond(VectorType &vec_cor, const VectorType &vec_def, const Filter_ &filter)
Applies the preconditioner onto a defect vector.
virtual void done_symbolic() override
Symbolic finalization method.
Polymorphic solver interface.
String class implementation.
String pad_front(size_type len, char c=' ') const
Pads the front of the string up to a desired length.
T_ sqrt(T_ x)
Returns the square-root of a value.
T_ abs(T_ x)
Returns the absolute value.
T_ sqr(T_ x)
Returns the square of a value.
T_ min(T_ a, T_ b)
Returns the minimum of two values.
Status
Solver status return codes enumeration.
@ progress
continue iteration (internal use only)
@ aborted
premature abort (solver aborted due to internal errors or preconditioner failure)
std::shared_ptr< GMRES< Matrix_, Filter_ > > new_gmres(const Matrix_ &matrix, const Filter_ &filter, Index krylov_dim, typename Matrix_::DataType inner_res_scale=typename Matrix_::DataType(0), std::shared_ptr< SolverBase< typename Matrix_::VectorTypeL > > precond=nullptr)
Creates a new GMRES solver object.
String stringify(const T_ &item)
Converts an item into a String.
String stringify_fp_sci(DataType_ value, int precision=0, int width=0, bool sign=false)
Prints a floating point value to a string in scientific notation.
std::uint64_t Index
Index data type.