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.
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.
Status
Solver status return codes enumeration.
@ progress
continue iteration (internal use only)
@ aborted
premature abort (solver aborted due to internal errors or preconditioner failure)
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.