opm-simulators
SystemTypes.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_SYSTEMTYPES_HEADER_INCLUDED
20 #define OPM_SYSTEMTYPES_HEADER_INCLUDED
21 
22 #include <opm/simulators/linalg/matrixblock.hh>
23 
24 #include <dune/istl/bcrsmatrix.hh>
25 #include <dune/istl/bvector.hh>
26 #include <dune/istl/multitypeblockmatrix.hh>
27 #include <dune/istl/multitypeblockvector.hh>
28 
29 namespace Opm
30 {
31 
32 // NOTE: These dimensions are hardcoded for standard 3-phase blackoil models
33 // (3 reservoir equations, 4 well equations). Models with a different number
34 // of conservation equations (e.g. EnablePolymerMW which adds an extra
35 // equation) are NOT supported by ISTLSolverSystem. A static_assert in
36 // ISTLSolverSystem guards against accidental misuse.
37 //
38 // To generalise, the types below (and the entire SystemPreconditioner /
39 // SystemPreconditionerFactory / WellMatrixMerger stack) would need to be
40 // templated on the dimension pair and the corresponding explicit
41 // instantiations updated.
42 inline constexpr int numResDofs = 3;
43 inline constexpr int numWellDofs = 4;
44 
45 template<typename Scalar>
46 using RRMatrix = Dune::BCRSMatrix<Opm::MatrixBlock<Scalar, numResDofs, numResDofs>>;
47 template<typename Scalar>
48 using RWMatrix = Dune::BCRSMatrix<Dune::FieldMatrix<Scalar, numResDofs, numWellDofs>>;
49 template<typename Scalar>
50 using WRMatrix = Dune::BCRSMatrix<Dune::FieldMatrix<Scalar, numWellDofs, numResDofs>>;
51 template<typename Scalar>
52 using WWMatrix = Dune::BCRSMatrix<Dune::FieldMatrix<Scalar, numWellDofs, numWellDofs>>;
53 
54 template<typename Scalar>
55 using ResVector = Dune::BlockVector<Dune::FieldVector<Scalar, numResDofs>>;
56 template<typename Scalar>
57 using WellVector = Dune::BlockVector<Dune::FieldVector<Scalar, numWellDofs>>;
58 template<typename Scalar>
59 using SystemVector = Dune::MultiTypeBlockVector<ResVector<Scalar>, WellVector<Scalar>>;
60 
61 // --------------------------------------------------------------------------
62 // SystemMatrix: a lightweight read-only view over a 2×2 block-matrix
63 // structure. All four sub-blocks are stored as const pointers; the actual
64 // data lives elsewhere (the reservoir block in ISTLSolver::matrix_, the
65 // well/coupling blocks in ISTLSolverSystem's merged-matrix members).
66 //
67 // Provides the operator interface required by Dune::MatrixAdapter and
68 // Dune::OverlappingSchwarzOperator (mv, usmv, N, M, field_type) as well as
69 // sub-block access via the index syntax S[_0][_0] used by
70 // SystemPreconditioner.
71 // --------------------------------------------------------------------------
72 template<typename Scalar> struct SystemMatrixRow0; // forward
73 template<typename Scalar> struct SystemMatrixRow1;
74 
75 template<typename Scalar>
77 {
78 public:
79  using size_type = std::size_t;
80  using field_type = Scalar;
81 
82  static constexpr size_type N() { return 2; }
83  static constexpr size_type M() { return 2; }
84 
85  // Block pointers — set directly by the owning solver.
86  const RRMatrix<Scalar>* A = nullptr; // (0,0) reservoir
87  const RWMatrix<Scalar>* C = nullptr; // (0,1) reservoir–well coupling
88  const WRMatrix<Scalar>* B = nullptr; // (1,0) well–reservoir coupling
89  const WWMatrix<Scalar>* D = nullptr; // (1,1) well
90 
91  // Sub-block access: S[_0][_0], S[_0][_1], S[_1][_0], S[_1][_1]
92  inline SystemMatrixRow0<Scalar> operator[](Dune::index_constant<0>) const;
93  inline SystemMatrixRow1<Scalar> operator[](Dune::index_constant<1>) const;
94 
95  // Matrix-vector products required by Dune linear operators.
96  // y = S * x = (A*x0 + C*x1; B*x0 + D*x1)
97  // Achieved by: y0 = A*x0 (mv), then y0 += C*x1 (umv); similarly for y1.
98  void mv(const SystemVector<Scalar>& x, SystemVector<Scalar>& y) const
99  {
100  using namespace Dune::Indices;
101  A->mv (x[_0], y[_0]); C->umv(x[_1], y[_0]);
102  B->mv (x[_0], y[_1]); D->umv(x[_1], y[_1]);
103  }
104 
105  // y += S * x = (y0 += A*x0 + C*x1; y1 += B*x0 + D*x1)
106  void umv(const SystemVector<Scalar>& x, SystemVector<Scalar>& y) const
107  {
108  using namespace Dune::Indices;
109  A->umv(x[_0], y[_0]); C->umv(x[_1], y[_0]);
110  B->umv(x[_0], y[_1]); D->umv(x[_1], y[_1]);
111  }
112 
113  // y += alpha * S * x = (y0 += alpha*(A*x0 + C*x1); y1 += alpha*(B*x0 + D*x1))
114  void usmv(field_type alpha, const SystemVector<Scalar>& x, SystemVector<Scalar>& y) const
115  {
116  using namespace Dune::Indices;
117  A->usmv(alpha, x[_0], y[_0]); C->usmv(alpha, x[_1], y[_0]);
118  B->usmv(alpha, x[_0], y[_1]); D->usmv(alpha, x[_1], y[_1]);
119  }
120 };
121 
122 // Row proxies for S[row][col] — simple aggregates, no back-pointers.
123 template<typename Scalar>
124 struct SystemMatrixRow0
125 {
126  const RRMatrix<Scalar>& A;
127  const RWMatrix<Scalar>& C;
128  const RRMatrix<Scalar>& operator[](Dune::index_constant<0>) const { return A; }
129  const RWMatrix<Scalar>& operator[](Dune::index_constant<1>) const { return C; }
130 };
131 
132 template<typename Scalar>
133 struct SystemMatrixRow1
134 {
135  const WRMatrix<Scalar>& B;
136  const WWMatrix<Scalar>& D;
137  const WRMatrix<Scalar>& operator[](Dune::index_constant<0>) const { return B; }
138  const WWMatrix<Scalar>& operator[](Dune::index_constant<1>) const { return D; }
139 };
140 
141 template<typename Scalar>
142 SystemMatrixRow0<Scalar> SystemMatrix<Scalar>::operator[](Dune::index_constant<0>) const
143 { return {*A, *C}; }
144 
145 template<typename Scalar>
146 SystemMatrixRow1<Scalar> SystemMatrix<Scalar>::operator[](Dune::index_constant<1>) const
147 { return {*B, *D}; }
148 
149 } // namespace Opm
150 
151 #endif // OPM_SYSTEMTYPES_HEADER_INCLUDED
Definition: SystemTypes.hpp:76
Definition: SystemTypes.hpp:72
Structs needed for tpfalinearizer and its gpuparams struct extracted to be defined in one place that ...
Definition: blackoilbioeffectsmodules.hh:45
Definition: SystemTypes.hpp:73