46 typename IterativeSolver::backend_type,
47 typename Precond::backend_type>::value,
48 "Backends for preconditioner and iterative solver should be compatible");
52 typedef typename IterativeSolver::backend_type backend_type;
53 typedef typename backend_type::matrix matrix;
54 typedef typename backend_type::vector vector;
56 typedef typename backend_type::value_type value_type;
57 typedef typename backend_type::params backend_params;
58 typedef typename BuiltinBackend<value_type>::matrix build_matrix;
60 typedef typename math::scalar_of<value_type>::type scalar_type;
69 scalar_type*
vec =
nullptr;
72 typename IterativeSolver::params
solver;
77 : ARCCORE_ALINA_PARAMS_IMPORT_VALUE(p,
nvec)
78 , ARCCORE_ALINA_PARAMS_IMPORT_VALUE(p,
vec)
79 , ARCCORE_ALINA_PARAMS_IMPORT_CHILD(p,
precond)
80 , ARCCORE_ALINA_PARAMS_IMPORT_CHILD(p,
solver)
82 p.check_params({
"nvec",
"vec",
"precond",
"solver" });
85 void get(
PropertyTree& p,
const std::string& path =
"")
const
87 ARCCORE_ALINA_PARAMS_EXPORT_CHILD(p, path,
nvec);
88 ARCCORE_ALINA_PARAMS_EXPORT_CHILD(p, path,
vec);
89 ARCCORE_ALINA_PARAMS_EXPORT_CHILD(p, path,
precond);
90 ARCCORE_ALINA_PARAMS_EXPORT_CHILD(p, path,
solver);
95 template <
class Matrix>
98 const backend_params& bprm = backend_params())
100 , n(backend::nbRow(A))
102 , S(backend::nbRow(A), prm.
solver, bprm)
103 , r(backend_type::create_vector(n, bprm))
105 , E(prm.nvec * prm.nvec, 0)
115 const backend_params& bprm = backend_params())
117 , n(backend::nbRow(*A))
119 , S(backend::nbRow(*A), prm.solver, bprm)
120 , r(backend_type::create_vector(n, bprm))
122 , E(prm.nvec * prm.nvec, 0)
128 template <
class Matrix>
129 void init(
const Matrix& A,
const backend_params& bprm)
131 precondition(prm.
nvec > 0 && prm.
vec !=
nullptr,
"Deflation vectors are not set!");
133 for (
int i = 0; i < prm.
nvec; ++i) {
135 Z[i] = backend_type::copy_vector(std::make_shared<numa_vector<scalar_type>>(irange), bprm);
138 std::vector<scalar_type> AZ(prm.
nvec);
139 std::fill(E.begin(), E.end(), math::zero<scalar_type>());
140 for (ptrdiff_t i = 0; i < static_cast<ptrdiff_t>(n); ++i) {
141 std::fill(AZ.begin(), AZ.end(), math::zero<scalar_type>());
142 for (
auto a = backend::row_begin(A, i); a; ++a) {
143 for (
int j = 0; j < prm.
nvec; ++j) {
144 AZ[j] += a.value() * prm.
vec[j * n + a.col()];
148 for (
int ii = 0, k = 0; ii < prm.nvec; ++ii) {
149 for (
int jj = 0; jj < prm.nvec; ++jj, ++k) {
150 E[k] += prm.vec[i + ii * n] * AZ[jj];
155 std::vector<scalar_type> t(E.size());
156 std::vector<int> p(prm.nvec);
157 detail::inverse(prm.nvec, E.data(), t.data(), p.data());
177 template <
class Matrix,
class Vec1,
class Vec2>
181 return S(A, *
this, rhs, x);
192 template <
class Vec1,
class Vec2>
196 return S(*
this, rhs, x);
199 template <
class Vec1,
class Vec2>
200 void apply(
const Vec1& rhs, Vec2&& x)
const
206 template <
class Vec1,
class Vec2>
207 void project(
const Vec1& b, Vec2& x)
const
210 backend::residual(b, P.system_matrix(), x, *r);
211 std::fill(d.begin(), d.end(), math::zero<scalar_type>());
212 for (
int j = 0; j < prm.
nvec; ++j) {
213 auto fj = backend::inner_product(*Z[j], *r);
214 for (
int i = 0; i < prm.
nvec; ++i)
215 d[i] += E[i * prm.
nvec + j] * fj;
217 backend::lin_comb(prm.
nvec, d, Z, 1, x);
241 return P.system_matrix_ptr();
244 typename Precond::matrix
const& system_matrix()
const
246 return P.system_matrix();
263 return backend::bytes(S) + backend::bytes(P);
266 friend std::ostream& operator<<(std::ostream& os,
const DeflatedSolver& p)
268 return os <<
"Solver\n======\n"
270 <<
"Preconditioner\n==============\n"
283 std::shared_ptr<vector> r;
284 std::vector<std::shared_ptr<vector>> Z;
285 std::vector<scalar_type> E;
286 mutable std::vector<scalar_type> d;