21#ifndef OPM_AMGX_PRECONDITIONER_HEADER_INCLUDED
22#define OPM_AMGX_PRECONDITIONER_HEADER_INCLUDED
24#include <opm/common/ErrorMacros.hpp>
25#include <opm/common/TimingMacros.hpp>
26#include <opm/simulators/linalg/PreconditionerWithUpdate.hpp>
27#include <opm/simulators/linalg/PropertyTree.hpp>
29#include <dune/common/fmatrix.hh>
30#include <dune/istl/bcrsmatrix.hh>
44 int determinism_flag = 0;
45 int print_grid_stats = 0;
46 int print_solve_stats = 0;
47 std::string solver =
"AMG";
48 std::string algorithm =
"CLASSICAL";
49 std::string interpolator =
"D2";
50 std::string selector =
"PMIS";
51 std::string smoother =
"BLOCK_JACOBI";
54 double strength_threshold = 0.5;
58 determinism_flag = prm.
get<
int>(
"determinism_flag", determinism_flag);
59 print_grid_stats = prm.
get<
int>(
"print_grid_stats", print_grid_stats);
60 print_solve_stats = prm.
get<
int>(
"print_solve_stats", print_solve_stats);
61 solver = prm.
get<std::string>(
"solver", solver);
62 algorithm = prm.
get<std::string>(
"algorithm", algorithm);
63 interpolator = prm.
get<std::string>(
"interpolator", interpolator);
64 selector = prm.
get<std::string>(
"selector", selector);
65 smoother = prm.
get<std::string>(
"smoother", smoother);
66 presweeps = prm.
get<
int>(
"presweeps", presweeps);
67 postsweeps = prm.
get<
int>(
"postsweeps", postsweeps);
68 strength_threshold = prm.
get<
double>(
"strength_threshold", strength_threshold);
69 max_iters = prm.
get<
int>(
"max_iters", max_iters);
72 std::string toString()
const {
73 return "config_version=2, "
74 "determinism_flag=" + std::to_string(determinism_flag) +
", "
75 "print_grid_stats=" + std::to_string(print_grid_stats) +
", "
76 "print_solve_stats=" + std::to_string(print_solve_stats) +
", "
77 "solver=" + solver +
", "
78 "algorithm=" + algorithm +
", "
79 "interpolator=" + interpolator +
", "
80 "selector=" + selector +
", "
81 "smoother=" + smoother +
", "
82 "presweeps=" + std::to_string(presweeps) +
", "
83 "postsweeps=" + std::to_string(postsweeps) +
", "
84 "strength_threshold=" + std::to_string(strength_threshold) +
", "
85 "max_iters=" + std::to_string(max_iters);
100template<
class M,
class X,
class Y>
115 static constexpr int block_size = 1;
128 , nnz_(A.nonzeroes())
130 OPM_TIMEBLOCK(prec_construct);
134 AMGX_SAFE_CALL(AMGX_config_create(&cfg_, config.toString().c_str()));
135 AMGX_SAFE_CALL(AMGX_resources_create_simple(&rsrc_, cfg_));
138 setup_frequency_ = prm.
get<
int>(
"setup_frequency", 30);
142 if constexpr (std::is_same_v<matrix_field_type, double> && std::is_same_v<vector_field_type, double>) {
143 amgx_mode = AMGX_mode_dDDI;
144 }
else if constexpr (std::is_same_v<matrix_field_type, float> && std::is_same_v<vector_field_type, double>) {
145 amgx_mode = AMGX_mode_dDFI;
146 }
else if constexpr (std::is_same_v<matrix_field_type, float> && std::is_same_v<vector_field_type, float>) {
147 amgx_mode = AMGX_mode_dFFI;
149 OPM_THROW(std::runtime_error,
"Unsupported combination of matrix and vector types in AmgxPreconditioner");
153 AMGX_SAFE_CALL(AMGX_solver_create(&solver_, rsrc_, amgx_mode, cfg_));
154 AMGX_SAFE_CALL(AMGX_matrix_create(&A_amgx_, rsrc_, amgx_mode));
155 AMGX_SAFE_CALL(AMGX_vector_create(&x_amgx_, rsrc_, amgx_mode));
156 AMGX_SAFE_CALL(AMGX_vector_create(&b_amgx_, rsrc_, amgx_mode));
159 std::vector<int> row_ptrs(N_ + 1);
160 std::vector<int> col_indices(nnz_);
161 setupSparsityPattern(row_ptrs, col_indices);
166 AMGX_SAFE_CALL(AMGX_matrix_upload_all(A_amgx_, N_, nnz_, block_size, block_size,
167 row_ptrs.data(), col_indices.data(),
182 AMGX_SAFE_CALL(AMGX_solver_destroy(solver_));
185 AMGX_SAFE_CALL(AMGX_vector_destroy(x_amgx_));
188 AMGX_SAFE_CALL(AMGX_vector_destroy(b_amgx_));
191 AMGX_SAFE_CALL(AMGX_matrix_destroy(A_amgx_));
210 void pre(X& , Y& )
override {
222 void apply(X& v,
const Y& d)
override
224 OPM_TIMEBLOCK(prec_apply);
227 AMGX_SAFE_CALL(AMGX_vector_upload(x_amgx_, N_, block_size, &v[0][0]));
228 AMGX_SAFE_CALL(AMGX_vector_upload(b_amgx_, N_, block_size, &d[0][0]));
231 AMGX_SAFE_CALL(AMGX_solver_solve(solver_, b_amgx_, x_amgx_));
234 AMGX_SAFE_CALL(AMGX_vector_download(x_amgx_, &v[0][0]));
254 OPM_TIMEBLOCK(prec_update);
256 if (update_counter_ == 0) {
257 AMGX_SAFE_CALL(AMGX_solver_setup(solver_, A_amgx_));
259 AMGX_SAFE_CALL(AMGX_solver_resetup(solver_, A_amgx_));
263 if (update_counter_ >= setup_frequency_) {
273 Dune::SolverCategory::Category
category()
const override
275 return Dune::SolverCategory::sequential;
299 void setupSparsityPattern(std::vector<int>& row_ptrs, std::vector<int>& col_indices)
303 for (
auto row = A_.begin(); row != A_.end(); ++row) {
304 for (
auto col = row->begin(); col != row->end(); ++col) {
305 col_indices[pos++] = col.index();
307 row_ptrs[row.index() + 1] = pos;
318 void copyMatrixToAmgx()
328 AMGX_SAFE_CALL(AMGX_matrix_replace_coefficients(A_amgx_, N_, nnz_, values,
nullptr));
335 int setup_frequency_ = -1;
336 int update_counter_ = 0;
338 AMGX_config_handle cfg_ =
nullptr;
339 AMGX_resources_handle rsrc_ =
nullptr;
340 AMGX_solver_handle solver_ =
nullptr;
341 AMGX_matrix_handle A_amgx_ =
nullptr;
342 AMGX_vector_handle x_amgx_ =
nullptr;
343 AMGX_vector_handle b_amgx_ =
nullptr;
Wrapper for AMGX's AMG preconditioner.
Definition AmgxPreconditioner.hpp:102
bool hasPerfectUpdate() const override
Checks if the preconditioner has a perfect update.
Definition AmgxPreconditioner.hpp:283
Y range_type
The range type of the preconditioner.
Definition AmgxPreconditioner.hpp:111
void update() override
Updates the preconditioner with the current matrix values.
Definition AmgxPreconditioner.hpp:252
void apply(X &v, const Y &d) override
Applies the preconditioner to a vector.
Definition AmgxPreconditioner.hpp:222
typename M::field_type matrix_field_type
The field type of the matrix.
Definition AmgxPreconditioner.hpp:107
AmgxPreconditioner(const M &A, const Opm::PropertyTree prm)
Constructor for the AmgxPreconditioner class.
Definition AmgxPreconditioner.hpp:125
Dune::SolverCategory::Category category() const override
Returns the solver category.
Definition AmgxPreconditioner.hpp:273
void pre(X &, Y &) override
Pre-processing step before applying the preconditioner.
Definition AmgxPreconditioner.hpp:210
X domain_type
The domain type of the preconditioner.
Definition AmgxPreconditioner.hpp:109
M matrix_type
The matrix type the preconditioner is for.
Definition AmgxPreconditioner.hpp:105
typename X::field_type vector_field_type
The field type of the vectors.
Definition AmgxPreconditioner.hpp:113
~AmgxPreconditioner()
Destructor for the AmgxPreconditioner class.
Definition AmgxPreconditioner.hpp:177
void post(X &) override
Post-processing step after applying the preconditioner.
Definition AmgxPreconditioner.hpp:244
Interface class adding the update() method to the preconditioner interface.
Definition PreconditionerWithUpdate.hpp:32
Hierarchical collection of key/value pairs.
Definition PropertyTree.hpp:39
T get(const std::string &key) const
Retrieve property value given hierarchical property key.
Definition PropertyTree.cpp:59
Configuration structure for AMGX parameters.
Definition AmgxPreconditioner.hpp:43