extractMatrix.hpp
Go to the documentation of this file.
1/*
2 Copyright 2021 SINTEF Digital, Mathematics and Cybernetics.
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
20#ifndef OPM_EXTRACT_MATRIX_HEADER_INCLUDED
21#define OPM_EXTRACT_MATRIX_HEADER_INCLUDED
22
23#include <algorithm>
24#include <cassert>
25#include <cstddef>
26#include <vector>
27
28namespace Opm
29{
30
31namespace Details
32{
33
34 template <class Matrix>
35 void copySubMatrix(const Matrix& A, const std::vector<int>& indices, Matrix& B)
36 {
37 // Copy elements so that B_{i, j} = A_{indices[i], indices[j]}.
38 for (auto row = B.begin(); row != B.end(); ++row) {
39 for (auto col = row->begin(); col != row->end(); ++col) {
40 *col = A[indices[row.index()]][indices[col.index()]];
41 }
42 }
43 }
44
45
46 template <class Matrix>
47 Matrix extractMatrix(const Matrix& m, const std::vector<int>& indices)
48 {
49 assert(std::is_sorted(indices.begin(), indices.end()));
50
51 // Set up reverse index map.
52 const std::size_t n = indices.size();
53 std::size_t newrow = 0;
54 enum { NotIncluded = -1 };
55 std::vector<int> index_map(m.N(), NotIncluded);
56 for (auto row = m.begin(); row != m.end(); ++row) {
57 const int row_index = row.index();
58 if (row_index == indices[newrow]) {
59 index_map[row_index] = newrow;
60 ++newrow;
61 if (newrow == n) {
62 break;
63 }
64 }
65 }
66 assert(newrow == n);
67
68 // Count nonzeroes.
69 std::size_t nnz = 0;
70 for (auto row = m.begin(); row != m.end(); ++row) {
71 if (index_map[row.index()] != NotIncluded) {
72 for (auto col = row->begin(); col != row->end(); ++col) {
73 if (index_map[col.index()] != NotIncluded) {
74 ++nnz;
75 }
76 }
77 }
78 }
79
80 // Create the matrix structure.
81 Matrix res(n, n, nnz, Matrix::row_wise);
82 auto from_row = m.begin();
83 for (auto row = res.createbegin(); row != res.createend(); ++row) {
84 // Move from_row to point to the row to be extracted.
85 while (static_cast<int>(from_row.index()) < indices[row.index()]) {
86 ++from_row;
87 }
88 assert(static_cast<int>(from_row.index()) == indices[row.index()]);
89 // Insert nonzeros for row.
90 for (auto from_col = from_row->begin(); from_col != from_row->end(); ++from_col) {
91 const int new_col = index_map[from_col.index()];
92 if (new_col != NotIncluded) {
93 row.insert(new_col);
94 }
95 }
96 }
97
98 copySubMatrix(m, indices, res);
99 return res;
100 }
101
102
103 template <class Vector>
104 Vector extractVector(const Vector& x, const std::vector<int>& indices)
105 {
106 Vector res(indices.size());
107 for (std::size_t ii = 0; ii < indices.size(); ++ii) {
108 res[ii] = x[indices[ii]];
109 }
110 return res;
111 }
112
113
114 template <class Vector>
115 void setGlobal(const Vector& x, const std::vector<int>& indices, Vector& global_x)
116 {
117 for (std::size_t ii = 0; ii < indices.size(); ++ii) {
118 global_x[indices[ii]] = x[ii];
119 }
120 }
121
122
123
124 template <class Matrix>
125 bool matrixEqual(const Matrix& m1, const Matrix& m2)
126 {
127 // Compare size and nonzeroes.
128 if (m1.N() != m2.N()) return false;
129 if (m1.M() != m2.M()) return false;
130 if (m1.nonzeroes() != m2.nonzeroes()) return false;
131
132 auto row1 = m1.begin();
133 auto row2 = m2.begin();
134 for (; row1 != m1.end(); ++row1, ++row2) {
135 if (row2 == m2.end()) return false;
136 if (row1.index() != row2.index()) return false;
137 auto col1 = row1->begin();
138 auto col2 = row2->begin();
139 for (; col1 != row1->end(); ++col1, ++col2) {
140 if (col2 == row2->end()) return false;
141 if (col1.index() != col2.index()) return false;
142 if (*col1 != *col2) return false;
143 }
144 }
145 return true;
146 }
147
148
149} // namespace Details
150
151
152} // namespace Opm
153
154#endif // OPM_EXTRACT_MATRIX_HEADER_INCLUDED
Vector extractVector(const Vector &x, const std::vector< int > &indices)
Definition: extractMatrix.hpp:104
void copySubMatrix(const Matrix &A, const std::vector< int > &indices, Matrix &B)
Definition: extractMatrix.hpp:35
void setGlobal(const Vector &x, const std::vector< int > &indices, Vector &global_x)
Definition: extractMatrix.hpp:115
bool matrixEqual(const Matrix &m1, const Matrix &m2)
Definition: extractMatrix.hpp:125
Matrix extractMatrix(const Matrix &m, const std::vector< int > &indices)
Definition: extractMatrix.hpp:47
Definition: BlackoilPhases.hpp:27