9#include <kernel/solver/iterative.hpp>
11#include <kernel/global/vector.hpp>
12#include <kernel/lafem/dense_matrix.hpp>
13#include <kernel/lafem/dense_vector.hpp>
14#include <kernel/util/random.hpp>
15#include <kernel/util/dist.hpp>
45 typedef Matrix_ MatrixType;
46 typedef Filter_ FilterType;
47 typedef typename MatrixType::VectorTypeR VectorType;
48 typedef typename MatrixType::DataType DataType;
49 typedef typename MatrixType::IndexType IndexType;
64 VectorType
_vec_q, _vec_r, _vec_v, _vec_t;
68 std::vector<VectorType>
_vec_P, _vec_dR, _vec_dX;
73 bool _shadow_space_setup, _random;
91 explicit IDRS(
const MatrixType& matrix,
const FilterType& filter,
Index krylov_dim,
92 std::shared_ptr<PrecondType> precond =
nullptr) :
97 _shadow_space_setup(false),
105 const MatrixType& matrix,
const FilterType& filter, std::shared_ptr<PrecondType> precond =
nullptr) :
106 BaseClass(
"IDRS", section_name, section, precond),
109 _shadow_space_setup(false),
116 auto krylov_dim_p = section->
query(
"krylov_dim");
117 if(!krylov_dim_p.second)
118 throw ParseError(
"IDRS config section is missing the mandatory krylov_dim!");
120 if(!krylov_dim_p.first.parse(this->_krylov_dim) || (this->_krylov_dim <=
Index(0)))
121 throw ParseError(section_name +
".krylov_dim", krylov_dim_p.first,
"a positive integer");
148 _vec_q = this->_system_matrix.create_vector_r();
194 virtual Status apply(VectorType& vec_sol,
const VectorType& vec_rhs)
override
197 this->_vec_res.copy(vec_rhs);
203 this->
_status = _apply_intern(vec_sol, vec_rhs);
213 virtual Status correct(VectorType& vec_sol,
const VectorType& vec_rhs)
override
216 this->_system_matrix.apply(this->_vec_res, vec_sol, vec_rhs, -DataType(1));
217 this->_system_filter.filter_def(this->_vec_res);
220 this->
_status = _apply_intern(vec_sol, vec_rhs);
238 _shadow_space_setup =
false;
245 void _set_shadow_space()
255 _vec_P.at(l).format(rng, DataType(0), DataType(1));
260 for (
Index i(0); i<j; ++i)
266 _shadow_space_setup =
true;
272 virtual Status _apply_intern(VectorType& vec_sol,
const VectorType& DOXY(vec_rhs))
274 IterationStats pre_iter(*
this);
275 Statistics::add_solver_expression(std::make_shared<ExpressionStartSolve>(this->
name()));
276 const MatrixType& matrix(this->_system_matrix);
277 const FilterType& filter(this->_system_filter);
289 if (!_shadow_space_setup)
295 IterationStats first_iter(*
this);
299 matrix.apply(_vec_v, _vec_r);
300 filter.filter_def(_vec_v);
305 first_iter.destroy();
309 om = _vec_v.dot(_vec_r) / _vec_v.dot(_vec_v);
310 _vec_dX.at(k).scale(_vec_r, om);
311 _vec_dR.at(k).scale(_vec_v, -om);
312 vec_sol.axpy(_vec_dX.at(k));
313 _vec_r.axpy(_vec_dR.at(k));
322 Statistics::add_solver_expression(std::make_shared<ExpressionEndSolve>(this->
name(), status, this->
get_num_iter()));
336 first_iter.destroy();
340 IterationStats stat(*
this);
349 _vec_q.scale(_vec_dR.at(0), -_dvec_c(0) );
351 _vec_q.axpy(_vec_dR.at(l), -_dvec_c(l));
358 matrix.apply(_vec_dR.at(oldest), _vec_v);
359 filter.filter_def(_vec_dR.at(oldest));
360 if(!this->
_apply_precond(this->_vec_t, this->_vec_dR.at(oldest), filter))
366 om = _vec_v.dot(_vec_t) / _vec_t.dot(_vec_t);
367 _vec_dR.at(oldest).copy(
_vec_q);
368 _vec_dR.at(oldest).axpy(_vec_t, -om);
371 _vec_dX.at(oldest).scale(_vec_dX.at(oldest), -_dvec_c(oldest));
372 for (
Index l(0); l < oldest; ++l)
373 _vec_dX.at(oldest).axpy(_vec_dX.at(l), -_dvec_c(l));
375 _vec_dX.at(oldest).axpy(_vec_dX.at(l), -_dvec_c(l));
376 _vec_dX.at(oldest).axpy(_vec_v, om);
378 matrix.apply(_vec_t, _vec_dX.at(oldest));
379 filter.filter_def(_vec_t);
384 _vec_dX.at(oldest).scale(_vec_dX.at(oldest), -_dvec_c(oldest));
385 for (
Index l(0); l < oldest; ++l)
386 _vec_dX.at(oldest).axpy(_vec_dX.at(l), -_dvec_c(l));
388 _vec_dX.at(oldest).axpy(_vec_dX.at(l), -_dvec_c(l));
389 _vec_dX.at(oldest).axpy(_vec_v, om);
391 matrix.apply( _vec_dR.at(oldest), _vec_dX.at(oldest));
392 filter.filter_def(_vec_dR.at(oldest));
393 _vec_t.copy(_vec_dR.at(oldest));
394 if(!this->
_apply_precond(this->_vec_dR.at(oldest), this->_vec_t, filter))
400 _vec_dR.at(oldest).scale(_vec_dR.at(oldest), DataType(-1));
404 _vec_r.axpy(_vec_dR.at(oldest));
405 vec_sol.axpy(_vec_dX.at(oldest));
414 _dvec_dm(l,
_vec_P.at(l).dot(_vec_dR.at(oldest)) );
415 _dmat_M( l, oldest, _dvec_dm(l));
423 Statistics::add_solver_expression(std::make_shared<ExpressionEndSolve>(this->
name(), status, this->
get_num_iter()));
446 template<
typename Matrix_,
typename Filter_>
447 inline std::shared_ptr<IDRS<Matrix_, Filter_>>
new_idrs(
448 const Matrix_& matrix,
const Filter_& filter,
Index krylov_dim,
451 return std::make_shared<IDRS<Matrix_, Filter_>>(matrix, filter, krylov_dim, precond);
475 template<
typename Matrix_,
typename Filter_>
476 inline std::shared_ptr<IDRS<Matrix_, Filter_>>
new_idrs(
478 const Matrix_& matrix,
const Filter_& filter,
481 return std::make_shared<IDRS<Matrix_, Filter_>>(section_name, section, matrix, filter, precond);
#define XASSERT(expr)
Assertion macro definition.
static Comm world()
Returns a copy of the world communicator.
Dense data matrix class template.
void apply(DenseVector< DT_, IT_ > &r, const DenseVector< DT_, IT_ > &x) const
Calculate .
DenseMatrix inverse() const
Create an inverse of the current matrix.
Dense data vector class template.
void axpy(const DenseVector &x, const DT_ alpha=DT_(1))
Calculate .
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.
Pseudo-Random Number Generator.
std::uint64_t SeedType
seed type
IDR(s) solver implementation.
virtual ~IDRS()
Empty virtual destructor.
virtual Status apply(VectorType &vec_sol, const VectorType &vec_rhs) override
Solver application method.
DVector _dvec_m
local ("small") dense vectors
void reset_shadow_space(bool random=true)
Reset the shadow space before the next system will be solved.
virtual String name() const override
Returns a descriptive string.
std::vector< VectorType > _vec_P
n x s "matrices"
DMatrix _dmat_M
dense s x s - matrices
IDRS(const MatrixType &matrix, const FilterType &filter, Index krylov_dim, std::shared_ptr< PrecondType > precond=nullptr)
Constructor.
VectorType _vec_q
auxillary vectors from the algorithm
virtual void done_symbolic() override
Symbolic finalization method.
virtual Status correct(VectorType &vec_sol, const VectorType &vec_rhs) override
const FilterType & _system_filter
the filter for the solver
VectorType _vec_res
real (unpreconditioned) residual
virtual void set_krylov_dim(Index krylov_dim)
Sets the inner Krylov space dimension.
virtual void init_symbolic() override
Symbolic initialization method.
const MatrixType & _system_matrix
the matrix for the solver
Index _krylov_dim
krylov dimension (s)
void set_plot_name(const String &plot_name)
Sets the plot name of the solver.
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.
virtual Status _set_new_defect(const VectorType &vec_def, const VectorType &vec_sol)
Internal function: sets the new (next) defect vector.
virtual void plot_summary() const
Plot a summary of the last solver run.
virtual Status _set_initial_defect(const VectorType &vec_def, const VectorType &vec_sol)
Internal function: sets the initial defect vector.
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.
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< IDRS< Matrix_, Filter_ > > new_idrs(const Matrix_ &matrix, const Filter_ &filter, Index krylov_dim, std::shared_ptr< SolverBase< typename Matrix_::VectorTypeL > > precond=nullptr)
Creates a new IDR(s) solver object.
String stringify(const T_ &item)
Converts an item into a String.
std::uint64_t Index
Index data type.