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>
99 const backend_params& bprm = backend_params())
101 , n(backend::nbRow(A))
102 , P(context, A, prm.
precond, bprm)
103 , S(context, backend::nbRow(A), prm.
solver, bprm)
104 , r(backend_type::create_vector(n, bprm))
106 , E(prm.nvec * prm.nvec, 0)
115 std::shared_ptr<build_matrix> A,
117 const backend_params& bprm = backend_params())
119 , n(backend::nbRow(*A))
120 , P(context, A, prm.
precond, bprm)
121 , S(context, backend::nbRow(*A), prm.solver, bprm)
122 , r(backend_type::create_vector(n, bprm))
124 , E(prm.nvec * prm.nvec, 0)
130 template <
class Matrix>
131 void init(
const Matrix& A,
const backend_params& bprm)
133 precondition(prm.
nvec > 0 && prm.
vec !=
nullptr,
"Deflation vectors are not set!");
135 for (
int i = 0; i < prm.
nvec; ++i) {
137 Z[i] = backend_type::copy_vector(std::make_shared<numa_vector<scalar_type>>(irange), bprm);
140 std::vector<scalar_type> AZ(prm.
nvec);
141 std::fill(E.begin(), E.end(), math::zero<scalar_type>());
142 for (ptrdiff_t i = 0; i < static_cast<ptrdiff_t>(n); ++i) {
143 std::fill(AZ.begin(), AZ.end(), math::zero<scalar_type>());
144 for (
auto a = backend::row_begin(A, i); a; ++a) {
145 for (
int j = 0; j < prm.
nvec; ++j) {
146 AZ[j] += a.value() * prm.
vec[j * n + a.col()];
150 for (
int ii = 0, k = 0; ii < prm.nvec; ++ii) {
151 for (
int jj = 0; jj < prm.nvec; ++jj, ++k) {
152 E[k] += prm.vec[i + ii * n] * AZ[jj];
157 std::vector<scalar_type> t(E.size());
158 std::vector<int> p(prm.nvec);
159 detail::inverse(prm.nvec, E.data(), t.data(), p.data());
179 template <
class Matrix,
class Vec1,
class Vec2>
183 return S(A, *
this, rhs, x);
194 template <
class Vec1,
class Vec2>
198 return S(*
this, rhs, x);
201 template <
class Vec1,
class Vec2>
202 void apply(
const Vec1& rhs, Vec2&& x)
const
208 template <
class Vec1,
class Vec2>
209 void project(
const Vec1& b, Vec2& x)
const
212 backend::residual(b, P.system_matrix(), x, *r);
213 std::fill(d.begin(), d.end(), math::zero<scalar_type>());
214 for (
int j = 0; j < prm.
nvec; ++j) {
215 auto fj = backend::inner_product(*Z[j], *r);
216 for (
int i = 0; i < prm.
nvec; ++i)
217 d[i] += E[i * prm.
nvec + j] * fj;
219 backend::lin_comb(prm.
nvec, d, Z, 1, x);
243 return P.system_matrix_ptr();
246 typename Precond::matrix
const& system_matrix()
const
248 return P.system_matrix();
265 return backend::bytes(S) + backend::bytes(P);
268 friend std::ostream& operator<<(std::ostream& os,
const DeflatedSolver& p)
270 return os <<
"Solver\n======\n"
272 <<
"Preconditioner\n==============\n"
285 std::shared_ptr<vector> r;
286 std::vector<std::shared_ptr<vector>> Z;
287 std::vector<scalar_type> E;
288 mutable std::vector<scalar_type> d;