9#include <kernel/solver/iterative.hpp>
82 typedef Matrix_ MatrixType;
83 typedef Filter_ FilterType;
84 typedef typename MatrixType::VectorTypeR VectorType;
85 typedef typename MatrixType::DataType DataType;
102 std::vector<DataType>
_c, _s, _q;
104 std::vector<std::vector<DataType>>
_h;
125 explicit FGMRES(
const MatrixType& matrix,
const FilterType& filter,
Index krylov_dim,
126 DataType inner_res_scale = DataType(0), std::shared_ptr<PrecondType> precond =
nullptr) :
141 const MatrixType& matrix,
const FilterType& filter, std::shared_ptr<PrecondType> precond =
nullptr) :
142 BaseClass(
"FGMRES", section_name, section, precond),
154 auto inner_res_scale_p = section->
query(
"inner_res_scale");
155 if(inner_res_scale_p.second && (!inner_res_scale_p.first.parse(this->_inner_res_scale) || (this->_inner_res_scale < DataType(0))))
156 throw ParseError(section_name +
".inner_res_scale", inner_res_scale_p.first,
"a non-negative float");
159 auto krylov_dim_p = section->
query(
"krylov_dim");
160 if(!krylov_dim_p.second)
161 throw ParseError(
"FGMRES config section is missing the mandatory krylov_dim!");
163 if(!krylov_dim_p.first.parse(this->_krylov_dim) || (this->_krylov_dim <=
Index(0)))
164 throw ParseError(section_name +
".krylov_dim", krylov_dim_p.first,
"a positive integer");
204 _h.at(i).resize(i+1);
207 _vec_v.push_back(this->_system_matrix.create_vector_r());
243 XASSERT(inner_res_scale >= DataType(0));
248 virtual Status apply(VectorType& vec_sol,
const VectorType& vec_rhs)
override
251 this->_vec_v.at(0).copy(vec_rhs);
257 this->
_status = _apply_intern(vec_sol, vec_rhs);
263 virtual Status correct(VectorType& vec_sol,
const VectorType& vec_rhs)
override
266 this->_system_matrix.apply(this->_vec_v.at(0), vec_sol, vec_rhs, -DataType(1));
267 this->_system_filter.filter_def(this->_vec_v.at(0));
270 this->
_status = _apply_intern(vec_sol, vec_rhs);
276 virtual Status _apply_intern(VectorType& vec_sol,
const VectorType& vec_rhs)
279 Statistics::add_solver_expression(std::make_shared<ExpressionStartSolve>(this->
name()));
280 const MatrixType& matrix(this->_system_matrix);
281 const FilterType& filter(this->_system_filter);
299 this->_vec_v.at(0).scale(this->_vec_v.at(0), DataType(1) / _q.back());
306 if(!this->
_apply_precond(this->_vec_z.at(i), this->_vec_v.at(i), filter))
315 matrix.apply(this->_vec_v.at(i+1), this->_vec_z.at(i));
316 filter.filter_def(this->_vec_v.at(i+1));
319 for(
Index k(0); k <= i; ++k)
321 this->_h.at(i).at(k) = this->_vec_v.at(i+1).dot(this->_vec_v.at(k));
322 this->_vec_v.at(i+1).axpy(this->_vec_v.at(k), -this->_h.at(i).at(k));
326 DataType alpha = this->_vec_v.at(i+1).norm2();
327 this->_vec_v.at(i+1).scale(this->_vec_v.at(i+1), DataType(1) / alpha);
330 for(
Index k(0); k < i; ++k)
332 DataType t(this->_h.at(i).at(k));
333 this->_h.at(i).at(k ) = this->_c.at(k) * t + this->_s.at(k) * this->_h.at(i).at(k+1);
334 this->_h.at(i).at(k+1) = this->_s.at(k) * t - this->_c.at(k) * this->_h.at(i).at(k+1);
341 _s.push_back(alpha / beta);
342 _c.push_back(this->_h.at(i).at(i) / beta);
344 this->_h.at(i).at(i) = beta;
345 this->_q.push_back(this->_s.back() * this->_q.at(i));
346 this->_q.at(i) *= this->_c.back();
352 DataType def_cur =
Math::abs(this->_q.back());
365 if((def_cur <= _inner_res_scale * this->
_tol_abs) &&
392 for(
Index k(n); k > 0;)
395 this->_q.at(k) /= this->_h.at(k).at(k);
396 for(
Index j(k); j > 0;)
399 this->_q.at(j) -= this->_h.at(k).at(j) * this->_q.at(k);
404 for(
Index k(0); k < n; ++k)
405 vec_sol.axpy(this->_vec_z.at(k), this->_q.at(k));
408 matrix.apply(this->_vec_v.at(0), vec_sol, vec_rhs, -DataType(1));
409 filter.filter_def(this->_vec_v.at(0));
416 Statistics::add_solver_expression(std::make_shared<ExpressionEndSolve>(this->
name(), status, this->
get_num_iter()));
443 template<
typename Matrix_,
typename Filter_>
445 const Matrix_& matrix,
const Filter_& filter,
Index krylov_dim,
446 typename Matrix_::DataType inner_res_scale =
typename Matrix_::DataType(0),
449 return std::make_shared<FGMRES<Matrix_, Filter_>>(matrix, filter, krylov_dim, inner_res_scale, precond);
473 template<
typename Matrix_,
typename Filter_>
476 const Matrix_& matrix,
const Filter_& filter,
479 return std::make_shared<FGMRES<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.
FGMRES(k) solver implementation.
virtual void done_symbolic() override
Symbolic finalization method.
virtual void set_inner_res_scale(DataType inner_res_scale)
Sets the inner residual scale.
DataType _inner_res_scale
inner pseudo-residual scaling factor, see the documentation of this class for details
virtual void init_symbolic() override
Symbolic initialization method.
std::vector< DataType > _c
Givens rotation coefficients.
const MatrixType & _system_matrix
the matrix for the solver
virtual void set_krylov_dim(Index krylov_dim)
Sets the inner Krylov space dimension.
virtual void force_defect_norm_calc(bool force) override
Forces the calculation of defect norms in every iteration (overridden)
const FilterType & _system_filter
the filter for the solver
virtual ~FGMRES()
Empty virtual destructor.
std::vector< std::vector< DataType > > _h
Hessenberg matrix.
Index _krylov_dim
krylov dimension
virtual Status apply(VectorType &vec_sol, const VectorType &vec_rhs) override
Solver application method.
virtual String name() const override
Returns a descriptive string.
FGMRES(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
std::vector< VectorType > _vec_v
krylov basis vectors
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< FGMRES< Matrix_, Filter_ > > new_fgmres(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 FGMRES 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.