diff --git a/opm/simulators/linalg/HyprePreconditioner.hpp b/opm/simulators/linalg/HyprePreconditioner.hpp index 9539967c7..17bbfec09 100644 --- a/opm/simulators/linalg/HyprePreconditioner.hpp +++ b/opm/simulators/linalg/HyprePreconditioner.hpp @@ -192,8 +192,10 @@ public: bool hasPerfectUpdate() const override { - // The Hypre preconditioner can depend on the values of the matrix, so it must be recreated - return false; + // The Hypre preconditioner can depend on the values of the matrix so it does not have perfect update. + // However, copying the matrix to Hypre requires to setup the solver again, so this is handled internally. + // So for ISTLSolver, we can return true. + return true; } private: diff --git a/opm/simulators/linalg/OwningTwoLevelPreconditioner.hpp b/opm/simulators/linalg/OwningTwoLevelPreconditioner.hpp index 5f32cccc6..98ab1cac1 100644 --- a/opm/simulators/linalg/OwningTwoLevelPreconditioner.hpp +++ b/opm/simulators/linalg/OwningTwoLevelPreconditioner.hpp @@ -174,7 +174,7 @@ public: } virtual bool hasPerfectUpdate() const override { - return false; + return twolevel_method_.hasPerfectUpdate(); } private: diff --git a/opm/simulators/linalg/PressureSolverPolicy.hpp b/opm/simulators/linalg/PressureSolverPolicy.hpp index 684ed1c77..0669a725a 100644 --- a/opm/simulators/linalg/PressureSolverPolicy.hpp +++ b/opm/simulators/linalg/PressureSolverPolicy.hpp @@ -88,6 +88,11 @@ namespace Amg return linsolver_->category(); } + bool hasPerfectUpdate() const + { + return linsolver_->preconditioner().hasPerfectUpdate(); + } + void apply(X& x, X& b, double reduction, Dune::InverseOperatorResult& res) override { linsolver_->apply(x, b, reduction, res); diff --git a/opm/simulators/linalg/twolevelmethodcpr.hh b/opm/simulators/linalg/twolevelmethodcpr.hh index 97435c82c..fbf8638ed 100644 --- a/opm/simulators/linalg/twolevelmethodcpr.hh +++ b/opm/simulators/linalg/twolevelmethodcpr.hh @@ -495,6 +495,12 @@ public: { } + bool hasPerfectUpdate() const + { + // The two-level method has perfect update if both the finesmoother and coarse solver do. + return smoother_->hasPerfectUpdate() && coarseSolver_->hasPerfectUpdate(); + } + void apply(FineDomainType& v, const FineRangeType& d) { FineDomainType u(v);