opm-simulators
SystemPreconditionerFactory.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_SYSTEMPRECONDITIONERFACTORY_HEADER_INCLUDED
20 #define OPM_SYSTEMPRECONDITIONERFACTORY_HEADER_INCLUDED
21 
22 #include <opm/simulators/linalg/system/MultiComm.hpp>
23 #include <opm/simulators/linalg/system/SystemPreconditioner.hpp>
24 #include <opm/simulators/linalg/PreconditionerFactory.hpp>
25 #include <opm/simulators/linalg/system/SystemTypes.hpp>
26 
27 #include <dune/istl/operators.hh>
28 #include <dune/istl/paamg/pinfo.hh>
29 
30 namespace Opm
31 {
32 
33 template <class Operator, class Comm, typename>
34 struct StandardPreconditioners;
35 
36 template<typename Scalar>
37 using SystemSeqOp = Dune::MatrixAdapter<SystemMatrix<Scalar>, SystemVector<Scalar>, SystemVector<Scalar>>;
38 
39 #if HAVE_MPI
41  const Dune::JacComm&>;
42 template<typename Scalar>
43 using SystemParOp = Dune::OverlappingSchwarzOperator<SystemMatrix<Scalar>, SystemVector<Scalar>,
44  SystemVector<Scalar>, SystemComm>;
45 #endif
46 
47 // Full specialisations of StandardPreconditioners for the coupled system
48 // operators. Partial specialisations would be ambiguous with the generic
49 // serial factory (!is_gpu_operator_v guard), so full specialisations are
50 // used; detail:: helpers factor out the shared logic.
51 
52 namespace detail {
53 
54 template<typename Scalar>
55 void addSystemCprSeq()
56 {
57  using O = SystemSeqOp<Scalar>;
58  using F = PreconditionerFactory<O, Dune::Amg::SequentialInformation>;
59  using V = SystemVector<Scalar>;
60  using P = PropertyTree;
61 
62  F::addCreator("system_cpr",
63  [](const O& op, const P& prm,
64  const std::function<V()>& sysWeightCalc,
65  std::size_t pressureIndex) {
66  std::function<ResVector<Scalar>()> resWeightCalc;
67  if (sysWeightCalc) {
68  resWeightCalc = [sysWeightCalc]() {
69  return sysWeightCalc()[Dune::Indices::_0];
70  };
71  }
72  return std::make_shared<SystemPreconditioner<Scalar, SeqResOperator<Scalar>>>(
73  op.getmat(), resWeightCalc, pressureIndex, prm);
74  });
75 }
76 
77 #if HAVE_MPI
78 // Register a sequential (non-MPI) version of the system_cpr preconditioner
79 // for the parallel operator. This allows each MPI rank to apply a local,
80 // communication‑free CPR preconditioner inside the overlapping Schwarz
81 // framework. It is a lightweight alternative to the fully parallel
82 // preconditioner registered by addSystemCprPar().
83 template<typename Scalar>
84 void addSystemCprParSeq()
85 {
86  using O = SystemParOp<Scalar>;
87  using F = PreconditionerFactory<O, Dune::Amg::SequentialInformation>;
88  using V = SystemVector<Scalar>;
89  using P = PropertyTree;
90 
91  F::addCreator("system_cpr",
92  [](const O& op, const P& prm,
93  const std::function<V()>& sysWeightCalc,
94  std::size_t pressureIndex) {
95  std::function<ResVector<Scalar>()> resWeightCalc;
96  if (sysWeightCalc) {
97  resWeightCalc = [sysWeightCalc]() {
98  return sysWeightCalc()[Dune::Indices::_0];
99  };
100  }
101  return std::make_shared<SystemPreconditioner<Scalar, SeqResOperator<Scalar>>>(
102  op.getmat(), resWeightCalc, pressureIndex, prm);
103  });
104 }
105 
106 template<typename Scalar>
107 void addSystemCprPar()
108 {
109  using O = SystemParOp<Scalar>;
110  using F = PreconditionerFactory<O, SystemComm>;
111  using V = SystemVector<Scalar>;
112  using P = PropertyTree;
113 
114  F::addCreator("system_cpr",
115  [](const O& op, const P& prm,
116  const std::function<V()>& sysWeightCalc,
117  std::size_t pressureIndex,
118  const SystemComm& comm) {
119  std::function<ResVector<Scalar>()> resWeightCalc;
120  if (sysWeightCalc) {
121  resWeightCalc = [sysWeightCalc]() {
122  return sysWeightCalc()[Dune::Indices::_0];
123  };
124  }
125  const auto& resComm = comm[Dune::Indices::_0];
126  return std::make_shared<SystemPreconditioner<Scalar, ParResOperator<Scalar>, ParResComm>>(
127  op.getmat(), resWeightCalc, pressureIndex, prm, resComm);
128  });
129 }
130 #endif
131 
132 } // namespace detail
133 
134 template <>
135 struct StandardPreconditioners<SystemSeqOp<double>, Dune::Amg::SequentialInformation, void> {
136  static void add() { detail::addSystemCprSeq<double>(); }
137 };
138 
139 template <>
140 struct StandardPreconditioners<SystemSeqOp<float>, Dune::Amg::SequentialInformation, void> {
141  static void add() { detail::addSystemCprSeq<float>(); }
142 };
143 
144 #if HAVE_MPI
145 template <>
146 struct StandardPreconditioners<SystemParOp<double>, Dune::Amg::SequentialInformation, void> {
147  static void add() { detail::addSystemCprParSeq<double>(); }
148 };
149 
150 template <>
151 struct StandardPreconditioners<SystemParOp<float>, Dune::Amg::SequentialInformation, void> {
152  static void add() { detail::addSystemCprParSeq<float>(); }
153 };
154 
155 template <>
156 struct StandardPreconditioners<SystemParOp<double>, SystemComm, void> {
157  static void add() { detail::addSystemCprPar<double>(); }
158 };
159 
160 template <>
161 struct StandardPreconditioners<SystemParOp<float>, SystemComm, void> {
162  static void add() { detail::addSystemCprPar<float>(); }
163 };
164 #endif
165 
166 } // namespace Opm
167 
168 #endif // OPM_SYSTEMPRECONDITIONERFACTORY_HEADER_INCLUDED
Definition: MultiComm.hpp:118
Definition: fvbaseprimaryvariables.hh:161
Structs needed for tpfalinearizer and its gpuparams struct extracted to be defined in one place that ...
Definition: blackoilbioeffectsmodules.hh:45
Definition: StandardPreconditioners_mpi.hpp:134