MatrixInverse.hpp
Go to the documentation of this file.
1 //===========================================================================
2 //
3 // File: MatrixInverse.hpp<2>
4 //
5 // Created: Wed Sep 3 14:49:08 2008
6 //
7 // Author(s): Atgeirr F Rasmussen <atgeirr@sintef.no>
8 // Bj�rn Spjelkavik <bsp@sintef.no>
9 //
10 // $Date$
11 //
12 // $Revision$
13 //
14 //===========================================================================
15 
16 /*
17  Copyright 2009, 2010 SINTEF ICT, Applied Mathematics.
18  Copyright 2009, 2010 Statoil ASA.
19 
20  This file is part of The Open Reservoir Simulator Project (OpenRS).
21 
22  OpenRS is free software: you can redistribute it and/or modify
23  it under the terms of the GNU General Public License as published by
24  the Free Software Foundation, either version 3 of the License, or
25  (at your option) any later version.
26 
27  OpenRS is distributed in the hope that it will be useful,
28  but WITHOUT ANY WARRANTY; without even the implied warranty of
29  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30  GNU General Public License for more details.
31 
32  You should have received a copy of the GNU General Public License
33  along with OpenRS. If not, see <http://www.gnu.org/licenses/>.
34 */
35 
36 #ifndef OPENRS_MATRIXINVERSE_HEADER
37 #define OPENRS_MATRIXINVERSE_HEADER
38 
39 #include <type_traits>
40 
46 namespace Opm {
47 
48 
49  template <typename M>
50  M inverse2x2(const M& m)
51  {
52  // Because then the divisions below would compile but not be correct, we must guard
53  // against integral types.
54  typedef typename M::value_type T;
55  static_assert(!std::is_integral<T>::value, "");
56  assert(m.numRows() == 2 && m.numCols() == 2);
57 
58  T det = m(0,0)*m(1,1) - m(0,1)*m(1,0);
59  M mi(2, 2, (double*)0);
60  mi(0,0) = m(1,1);
61  mi(1,0) = -m(1,0);
62  mi(0,1) = -m(0,1);
63  mi(1,1) = m(0,0);
64  mi /= det;
65  return mi;
66  }
67 
68  template <typename M>
69  M matprod(const M& m1, const M& m2)
70  {
71  assert(m1.numCols() == m2.numRows());
72  int num_contracting = m1.numCols();
73  M m(m1.numRows(), m2.numCols(), (double*)0);
74  for (int r = 0; r < m1.numRows(); ++r) {
75  for (int c = 0; c < m2.numCols(); ++c) {
76  m(r, c) = 0.0;
77  for (int kk = 0; kk < num_contracting; ++kk) {
78  m(r, c) += m1(r, kk)*m2(kk, c);
79  }
80  }
81  }
82  return m;
83  }
84 
85  template <typename M>
86  M inverse3x3(const M& m)
87  {
88  // Because then the divisions below would compile but not be correct, we must guard
89  // against integral types.
90  typedef typename M::value_type T;
91  static_assert(!std::is_integral<T>::value, "");
92  assert(m.numRows() == 3 && m.numCols() == 3);
93 // double det = m(0,0)*(m(1,1)*m(2,2)-m(1,2)*m(2,1))
94 // - m(0,1)*(m(1,0)*m(2,2)-m(1,2)*m(2,0))
95 // + m(0,2)*(m(1,0)*m(2,1)-m(1,1)*m(2,0));
96 
97  T a = m(0,0);
98  T b = m(0,1);
99  T c = m(0,2);
100  T d = m(1,0);
101  T e = m(1,1);
102  T f = m(1,2);
103  T g = m(2,0);
104  T h = m(2,1);
105  T i = m(2,2);
106  T t1 = (e-f*h/i);
107  T t2 = (c*h/i-b);
108  T t3 = (f*g/i-d);
109  T t4 = (a-c*g/i);
110  T x = t4*t1-t2*t3;
111 
112  M mi(3, 3, (double*)0);
113  mi(0,0) = t1/x;
114  mi(0,1) = t2/x;
115  mi(0,2) = -(c*t1+f*t2)/(i*x);
116  mi(1,0) = t3/x;
117  mi(1,1) = t4/x;
118  mi(1,2) = -(c*t3+f*t4)/(i*x);
119  mi(2,0) = -(g*t1+h*t3)/(i*x);
120  mi(2,1) = -(g*t2+h*t4)/(i*x);
121  mi(2,2) = 1/i+1/(i*i*x)*(c*(g*t1+h*t3)+f*(g*t2+h*t4));
122  return mi;
123  }
124 
125 
126 } // namespace Opm
127 
128 #endif // OPENRS_MATRIXINVERSE_HEADER
Definition: BlackoilFluid.hpp:31
M matprod(const M &m1, const M &m2)
Definition: MatrixInverse.hpp:69
M inverse3x3(const M &m)
Definition: MatrixInverse.hpp:86
M inverse2x2(const M &m)
Definition: MatrixInverse.hpp:50