matrixblock.hh
Go to the documentation of this file.
1// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2// vi: set et ts=4 sw=4 sts=4:
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 2 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 Consult the COPYING file in the top-level source directory of this
20 module for the precise wording of the license and the list of
21 copyright holders.
22*/
23#ifndef EWOMS_MATRIX_BLOCK_HH
24#define EWOMS_MATRIX_BLOCK_HH
25
26#include <dune/common/dynmatrix.hh>
27#include <dune/common/fmatrix.hh>
28#include <dune/common/typetraits.hh>
29
30#include <dune/istl/superlu.hh>
31#include <dune/istl/umfpack.hh>
32#include <dune/istl/istlexception.hh>
33#include <dune/istl/matrixutils.hh>
34
35#include <opm/common/Exceptions.hpp>
36
37#include <limits>
38
39namespace Opm {
40namespace detail {
41
42template <typename K, int m, int n>
43static inline void invertMatrix(Dune::FieldMatrix<K,m,n>& matrix)
44{
45 matrix.invert();
46}
47
48template <typename K>
49static inline void invertMatrix(Dune::FieldMatrix<K,1,1>& matrix)
50{
51 Dune::FieldMatrix<K,1,1> tmp(matrix);
53}
54
55template <typename K>
56static inline void invertMatrix(Dune::FieldMatrix<K,2,2>& matrix)
57{
58 Dune::FieldMatrix<K,2,2> tmp(matrix);
60}
61
62template <typename K>
63static inline void invertMatrix(Dune::FieldMatrix<K,3,3>& matrix)
64{
65 Dune::FieldMatrix<K,3,3> tmp(matrix);
67}
68
71template <template<class K> class Matrix, typename K>
72static inline K adjugateMatrix4(const Matrix<K>& matrix, Matrix<K>& inverse)
73{
74 inverse[0][0] = matrix[1][1] * matrix[2][2] * matrix[3][3] -
75 matrix[1][1] * matrix[2][3] * matrix[3][2] -
76 matrix[2][1] * matrix[1][2] * matrix[3][3] +
77 matrix[2][1] * matrix[1][3] * matrix[3][2] +
78 matrix[3][1] * matrix[1][2] * matrix[2][3] -
79 matrix[3][1] * matrix[1][3] * matrix[2][2];
80
81 inverse[1][0] = -matrix[1][0] * matrix[2][2] * matrix[3][3] +
82 matrix[1][0] * matrix[2][3] * matrix[3][2] +
83 matrix[2][0] * matrix[1][2] * matrix[3][3] -
84 matrix[2][0] * matrix[1][3] * matrix[3][2] -
85 matrix[3][0] * matrix[1][2] * matrix[2][3] +
86 matrix[3][0] * matrix[1][3] * matrix[2][2];
87
88 inverse[2][0] = matrix[1][0] * matrix[2][1] * matrix[3][3] -
89 matrix[1][0] * matrix[2][3] * matrix[3][1] -
90 matrix[2][0] * matrix[1][1] * matrix[3][3] +
91 matrix[2][0] * matrix[1][3] * matrix[3][1] +
92 matrix[3][0] * matrix[1][1] * matrix[2][3] -
93 matrix[3][0] * matrix[1][3] * matrix[2][1];
94
95 inverse[3][0] = -matrix[1][0] * matrix[2][1] * matrix[3][2] +
96 matrix[1][0] * matrix[2][2] * matrix[3][1] +
97 matrix[2][0] * matrix[1][1] * matrix[3][2] -
98 matrix[2][0] * matrix[1][2] * matrix[3][1] -
99 matrix[3][0] * matrix[1][1] * matrix[2][2] +
100 matrix[3][0] * matrix[1][2] * matrix[2][1];
101
102 inverse[0][1]= -matrix[0][1] * matrix[2][2] * matrix[3][3] +
103 matrix[0][1] * matrix[2][3] * matrix[3][2] +
104 matrix[2][1] * matrix[0][2] * matrix[3][3] -
105 matrix[2][1] * matrix[0][3] * matrix[3][2] -
106 matrix[3][1] * matrix[0][2] * matrix[2][3] +
107 matrix[3][1] * matrix[0][3] * matrix[2][2];
108
109 inverse[1][1] = matrix[0][0] * matrix[2][2] * matrix[3][3] -
110 matrix[0][0] * matrix[2][3] * matrix[3][2] -
111 matrix[2][0] * matrix[0][2] * matrix[3][3] +
112 matrix[2][0] * matrix[0][3] * matrix[3][2] +
113 matrix[3][0] * matrix[0][2] * matrix[2][3] -
114 matrix[3][0] * matrix[0][3] * matrix[2][2];
115
116 inverse[2][1] = -matrix[0][0] * matrix[2][1] * matrix[3][3] +
117 matrix[0][0] * matrix[2][3] * matrix[3][1] +
118 matrix[2][0] * matrix[0][1] * matrix[3][3] -
119 matrix[2][0] * matrix[0][3] * matrix[3][1] -
120 matrix[3][0] * matrix[0][1] * matrix[2][3] +
121 matrix[3][0] * matrix[0][3] * matrix[2][1];
122
123 inverse[3][1] = matrix[0][0] * matrix[2][1] * matrix[3][2] -
124 matrix[0][0] * matrix[2][2] * matrix[3][1] -
125 matrix[2][0] * matrix[0][1] * matrix[3][2] +
126 matrix[2][0] * matrix[0][2] * matrix[3][1] +
127 matrix[3][0] * matrix[0][1] * matrix[2][2] -
128 matrix[3][0] * matrix[0][2] * matrix[2][1];
129
130 inverse[0][2] = matrix[0][1] * matrix[1][2] * matrix[3][3] -
131 matrix[0][1] * matrix[1][3] * matrix[3][2] -
132 matrix[1][1] * matrix[0][2] * matrix[3][3] +
133 matrix[1][1] * matrix[0][3] * matrix[3][2] +
134 matrix[3][1] * matrix[0][2] * matrix[1][3] -
135 matrix[3][1] * matrix[0][3] * matrix[1][2];
136
137 inverse[1][2] = -matrix[0][0] * matrix[1][2] * matrix[3][3] +
138 matrix[0][0] * matrix[1][3] * matrix[3][2] +
139 matrix[1][0] * matrix[0][2] * matrix[3][3] -
140 matrix[1][0] * matrix[0][3] * matrix[3][2] -
141 matrix[3][0] * matrix[0][2] * matrix[1][3] +
142 matrix[3][0] * matrix[0][3] * matrix[1][2];
143
144 inverse[2][2] = matrix[0][0] * matrix[1][1] * matrix[3][3] -
145 matrix[0][0] * matrix[1][3] * matrix[3][1] -
146 matrix[1][0] * matrix[0][1] * matrix[3][3] +
147 matrix[1][0] * matrix[0][3] * matrix[3][1] +
148 matrix[3][0] * matrix[0][1] * matrix[1][3] -
149 matrix[3][0] * matrix[0][3] * matrix[1][1];
150
151 inverse[3][2] = -matrix[0][0] * matrix[1][1] * matrix[3][2] +
152 matrix[0][0] * matrix[1][2] * matrix[3][1] +
153 matrix[1][0] * matrix[0][1] * matrix[3][2] -
154 matrix[1][0] * matrix[0][2] * matrix[3][1] -
155 matrix[3][0] * matrix[0][1] * matrix[1][2] +
156 matrix[3][0] * matrix[0][2] * matrix[1][1];
157
158 inverse[0][3] = -matrix[0][1] * matrix[1][2] * matrix[2][3] +
159 matrix[0][1] * matrix[1][3] * matrix[2][2] +
160 matrix[1][1] * matrix[0][2] * matrix[2][3] -
161 matrix[1][1] * matrix[0][3] * matrix[2][2] -
162 matrix[2][1] * matrix[0][2] * matrix[1][3] +
163 matrix[2][1] * matrix[0][3] * matrix[1][2];
164
165 inverse[1][3] = matrix[0][0] * matrix[1][2] * matrix[2][3] -
166 matrix[0][0] * matrix[1][3] * matrix[2][2] -
167 matrix[1][0] * matrix[0][2] * matrix[2][3] +
168 matrix[1][0] * matrix[0][3] * matrix[2][2] +
169 matrix[2][0] * matrix[0][2] * matrix[1][3] -
170 matrix[2][0] * matrix[0][3] * matrix[1][2];
171
172 inverse[2][3] = -matrix[0][0] * matrix[1][1] * matrix[2][3] +
173 matrix[0][0] * matrix[1][3] * matrix[2][1] +
174 matrix[1][0] * matrix[0][1] * matrix[2][3] -
175 matrix[1][0] * matrix[0][3] * matrix[2][1] -
176 matrix[2][0] * matrix[0][1] * matrix[1][3] +
177 matrix[2][0] * matrix[0][3] * matrix[1][1];
178
179 inverse[3][3] = matrix[0][0] * matrix[1][1] * matrix[2][2] -
180 matrix[0][0] * matrix[1][2] * matrix[2][1] -
181 matrix[1][0] * matrix[0][1] * matrix[2][2] +
182 matrix[1][0] * matrix[0][2] * matrix[2][1] +
183 matrix[2][0] * matrix[0][1] * matrix[1][2] -
184 matrix[2][0] * matrix[0][2] * matrix[1][1];
185
186 return matrix[0][0] * inverse[0][0] + matrix[0][1] * inverse[1][0] +
187 matrix[0][2] * inverse[2][0] + matrix[0][3] * inverse[3][0];
188}
189
204template <template<class K> class Matrix, typename K>
205static inline K invertMatrix4(const Matrix<K>& matrix, Matrix<K>& inverse)
206{
207 const K det = adjugateMatrix4<Matrix, K>(matrix, inverse);
208
209 if (std::abs(det) < 1e-40) {
210 inverse = matrix;
211 try {
212 inverse.invert();
213 }
214 catch (const Dune::FMatrixError&) {
215 inverse = std::numeric_limits<K>::quiet_NaN();
216 DUNE_THROW(Dune::MatrixBlockError, "Singular matrix block");
217 }
218 }
219 else {
220 inverse *= 1.0 / det;
221 }
222
223 return det;
224}
225
226template<class K> using FMat4 = Dune::FieldMatrix<K,4,4>;
227
228template <typename K>
229static inline void invertMatrix(Dune::FieldMatrix<K,4,4>& matrix)
230{
231 FMat4<K> tmp(matrix);
232 invertMatrix4<FMat4>(tmp, matrix);
233}
234
235template <typename K>
236static inline void invertMatrix(Dune::DynamicMatrix<K>& matrix)
237{
238 // this function is only for 4 X 4 matrix
239 // for 4 X 4 matrix, using the invertMatrix() function above
240 // it is for temporary usage, mainly to reduce the huge burden of testing
241 // what algorithm should be used to invert 4 X 4 matrix will be handled
242 // as a seperate issue
243 if (matrix.rows() == 4) {
244 Dune::DynamicMatrix<K> A = matrix;
245 invertMatrix4(A, matrix);
246 return;
247 }
248
249 matrix.invert();
250}
251
252} // namespace detail
253
254template <class Scalar, int n, int m>
255class MatrixBlock : public Dune::FieldMatrix<Scalar, n, m>
256{
257public:
258 using BaseType = Dune::FieldMatrix<Scalar, n, m> ;
259
260 using BaseType::operator= ;
261 using BaseType::rows;
262 using BaseType::cols;
263
265 : BaseType(Scalar(0.0))
266 {}
267
268 explicit MatrixBlock(const Scalar value)
269 : BaseType(value)
270 {}
271
272 void invert()
274
275 const BaseType& asBase() const
276 { return static_cast<const BaseType&>(*this); }
277
279 { return static_cast<BaseType&>(*this); }
280};
281
282} // namespace Opm
283
284namespace Dune {
285
286template<class K, int n, int m>
287void print_row(std::ostream& s, const Opm::MatrixBlock<K, n, m>& A,
288 typename FieldMatrix<K, n, m>::size_type I,
289 typename FieldMatrix<K, n, m>::size_type J,
290 typename FieldMatrix<K, n, m>::size_type therow,
291 int width,
292 int precision)
293{ print_row(s, A.asBase(), I, J, therow, width, precision); }
294
295template <typename Scalar, int n, int m>
296struct MatrixDimension<Opm::MatrixBlock<Scalar, n, m> >
297 : public MatrixDimension<typename Opm::MatrixBlock<Scalar, n, m>::BaseType>
298{ };
299
300
301#if HAVE_SUITESPARSE_UMFPACK
305template <typename T, typename A, int n, int m>
306class UMFPack<BCRSMatrix<Opm::MatrixBlock<T, n, m>, A> >
307 : public UMFPack<BCRSMatrix<FieldMatrix<T, n, m>, A> >
308{
310 using Matrix = BCRSMatrix<FieldMatrix<T, n, m>, A>;
311
312public:
313 using RealMatrix = BCRSMatrix<Opm::MatrixBlock<T, n, m>, A>;
314
315 UMFPack(const RealMatrix& matrix, int verbose, bool)
316 : Base(reinterpret_cast<const Matrix&>(matrix), verbose)
317 {}
318};
319#endif
320
321#if HAVE_SUPERLU
325template <typename T, typename A, int n, int m>
326class SuperLU<BCRSMatrix<Opm::MatrixBlock<T, n, m>, A> >
327 : public SuperLU<BCRSMatrix<FieldMatrix<T, n, m>, A> >
328{
329 using Base = SuperLU<BCRSMatrix<FieldMatrix<T, n, m>, A> >;
330 using Matrix = BCRSMatrix<FieldMatrix<T, n, m>, A>;
331
332public:
333 using RealMatrix = BCRSMatrix<Opm::MatrixBlock<T, n, m>, A>;
334
335 SuperLU(const RealMatrix& matrix, int verb, bool reuse=true)
336 : Base(reinterpret_cast<const Matrix&>(matrix), verb, reuse)
337 {}
338};
339#endif
340
341template<typename T, int n, int m>
342struct IsNumber<Opm::MatrixBlock<T, n, m>>
343 : public IsNumber<Dune::FieldMatrix<T,n,m>>
344{};
345
346template<typename T, int n, int m>
347struct FieldTraits<Opm::MatrixBlock<T, n, m>>
348 : public FieldTraits<Dune::FieldMatrix<T,n,m>>
349{};
350
351} // end namespace Dune
352
353
354#endif
Definition: MSWellHelpers.hpp:29
Definition: matrixblock.hh:256
void invert()
Definition: matrixblock.hh:272
BaseType & asBase()
Definition: matrixblock.hh:278
const BaseType & asBase() const
Definition: matrixblock.hh:275
MatrixBlock()
Definition: matrixblock.hh:264
Dune::FieldMatrix< Scalar, n, m > BaseType
Definition: matrixblock.hh:258
MatrixBlock(const Scalar value)
Definition: matrixblock.hh:268
Definition: fvbaseprimaryvariables.hh:161
void print_row(std::ostream &s, const Opm::MatrixBlock< K, n, m > &A, typename FieldMatrix< K, n, m >::size_type I, typename FieldMatrix< K, n, m >::size_type J, typename FieldMatrix< K, n, m >::size_type therow, int width, int precision)
Definition: matrixblock.hh:287
static void invertMatrix(Dune::FieldMatrix< K, m, n > &matrix)
Definition: matrixblock.hh:43
static K adjugateMatrix4(const Matrix< K > &matrix, Matrix< K > &inverse)
Definition: matrixblock.hh:72
static K invertMatrix4(const Matrix< K > &matrix, Matrix< K > &inverse)
Definition: matrixblock.hh:205
Dune::FieldMatrix< K, 4, 4 > FMat4
Definition: matrixblock.hh:226
static void invertMatrix(Dune::DynamicMatrix< K > &matrix)
Definition: matrixblock.hh:236
Definition: blackoilbioeffectsmodules.hh:45