opm-simulators
Preconditioner2InverseOperator.hpp
1 /*
2  Copyright Equinor ASA 2026
3 
4  This file is part of the Open Porous Media project (OPM).
5 
6  OPM is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  OPM is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with OPM. If not, see <http://www.gnu.org/licenses/>.
18 */
19 #ifndef OPM_PRECONDITIONER2INVERSEOPERATOR_HEADER_INCLUDED
20 #define OPM_PRECONDITIONER2INVERSEOPERATOR_HEADER_INCLUDED
21 
22 #include <dune/common/shared_ptr.hh>
23 #include <dune/istl/preconditioner.hh>
24 #include <dune/istl/solver.hh>
25 
26 #include <memory>
27 
28 namespace Dune
29 {
30 
38 template<class X>
39 class Preconditioner2InverseOperator : public InverseOperator<X, X>
40 {
41 public:
42  using typename InverseOperator<X, X>::domain_type;
43  using typename InverseOperator<X, X>::range_type;
44  using typename InverseOperator<X, X>::field_type;
45  using typename InverseOperator<X, X>::real_type;
46  using typename InverseOperator<X, X>::scalar_real_type;
47 
48  using PreconditionerType = Preconditioner<X, X>;
49 
50  explicit Preconditioner2InverseOperator(PreconditionerType& prec)
51  : prec_(stackobject_to_shared_ptr(prec))
52  {
53  }
54 
55  explicit Preconditioner2InverseOperator(std::shared_ptr<PreconditionerType> prec)
56  : prec_(std::move(prec))
57  {
58  }
59 
60  void apply(X& x, X& b, InverseOperatorResult& res) override
61  {
62  prec_->pre(x, b);
63  // Preconditioners compute a correction/update, so start from zero to
64  // interpret this adapter as x = M^{-1} b.
65  x = 0;
66  prec_->apply(x, b);
67  prec_->post(x);
68 
69  // No residual norm is evaluated here; report one successful
70  // application rather than an iterative solve.
71  res.clear();
72  res.iterations = 1;
73  res.reduction = 1.0;
74  res.converged = true;
75  }
76 
77  void apply(X& x, X& b, [[maybe_unused]] double reduction, InverseOperatorResult& res) override
78  {
79  apply(x, b, res);
80  }
81 
82  SolverCategory::Category category() const override
83  {
84  return SolverCategory::category(*prec_);
85  }
86 
87 private:
88  // Non-owning alias when constructed from a reference, shared ownership
89  // when constructed from a shared_ptr.
90  std::shared_ptr<PreconditionerType> prec_;
91 };
92 
93 } // namespace Dune
94 
95 #endif // OPM_PRECONDITIONER2INVERSEOPERATOR_HEADER_INCLUDED
Definition: fvbaseprimaryvariables.hh:161
Adapter exposing a preconditioner through the inverse-operator interface.
Definition: Preconditioner2InverseOperator.hpp:39