19#ifndef OPM_WELLMATRIXMERGER_HEADER_INCLUDED
20#define OPM_WELLMATRIXMERGER_HEADER_INCLUDED
23#include <opm/grid/utility/SparseTable.hpp>
56 return !(*
this == other);
86 return !(*
this == other);
95 pattern.
rows = matrix.N();
96 pattern.
cols = matrix.M();
98 if constexpr (
requires { matrix.nonzeroes(); }) {
103 for (std::size_t rowIdx = 0; rowIdx < matrix.N(); ++rowIdx) {
104 for (
auto colIt = matrix[rowIdx].begin(); colIt != matrix[rowIdx].end(); ++colIt) {
116 if (matrix.N() != pattern.
rows || matrix.M() != pattern.
cols) {
127 std::size_t entryOffset = 0;
128 for (std::size_t rowIdx = 0; rowIdx < matrix.N(); ++rowIdx) {
129 if (pattern.
rowOffsets[rowIdx] != entryOffset) {
133 for (
auto colIt = matrix[rowIdx].begin(); colIt != matrix[rowIdx].end(); ++colIt) {
135 ||
static_cast<std::size_t
>(pattern.
columnIndices[entryOffset]) != colIt.index())
142 if (pattern.
rowOffsets[rowIdx + 1] != entryOffset) {
162template<
typename Scalar>
171 const std::vector<BMatrix>& bMatrices,
172 const std::vector<CMatrix>& cMatrices,
173 const std::vector<DMatrix>& dMatrices,
175 : numResDofs_(nResDofs)
176 , bMatrices_(bMatrices)
177 , cMatrices_(cMatrices)
178 , dMatrices_(dMatrices)
179 , wellCells_(wellCells)
186 const auto numWells = bMatrices_.size();
188 ||
static_cast<std::size_t
>(cachedStructure.
wellCells.size()) != numWells
189 || cachedStructure.
bPatterns.size() != numWells
190 || cachedStructure.
cPatterns.size() != numWells
191 || cachedStructure.
dPatterns.size() != numWells)
196 std::size_t totalWellDofs = 0;
197 for (std::size_t well = 0; well < numWells; ++well) {
198 totalWellDofs += dMatrices_[well].N();
200 const auto& cachedRow = cachedStructure.
wellCells[well];
201 const auto& currentRow = wellCells_[well];
202 if (!std::ranges::equal(cachedRow.begin(), cachedRow.end(), currentRow.begin(), currentRow.end())
220 structure.
bPatterns.reserve(bMatrices_.size());
221 structure.
cPatterns.reserve(cMatrices_.size());
222 structure.
dPatterns.reserve(dMatrices_.size());
224 for (std::size_t well = 0; well < bMatrices_.size(); ++well) {
238 mergeBMatrix(mergedB);
239 mergeCMatrix(mergedC);
240 mergeDMatrix(mergedD);
247 fillBValues(mergedB);
248 fillCValues(mergedC);
249 fillDValues(mergedD);
253 void validateInputs()
const
255 const auto numWells = bMatrices_.size();
256 assert(cMatrices_.size() == numWells);
257 assert(dMatrices_.size() == numWells);
258 assert(
static_cast<std::size_t
>(wellCells_.size()) == numWells);
260 for (std::size_t well = 0; well < numWells; ++well) {
261 const auto& B = bMatrices_[well];
262 const auto& C = cMatrices_[well];
263 const auto& D = dMatrices_[well];
264 const auto& cells = wellCells_[well];
266 assert(cells.size() == B.M());
267 assert(cells.size() == C.N());
268 assert(B.N() == C.M());
269 assert(B.N() == D.N());
270 assert(C.M() == D.M());
271 assert(D.N() == D.M());
275 template<
class Matrix>
276 static void initializeEmptyMatrix(Matrix& matrix, std::size_t rows, std::size_t cols)
278 matrix.setSize(rows, cols);
279 matrix.setBuildMode(Matrix::random);
280 for (std::size_t row = 0; row < rows; ++row) {
281 matrix.setrowsize(row, 0);
283 matrix.endrowsizes();
287 template<
class MatrixVectorT,
class DimensionFn>
288 static std::size_t sumMatrixDimension(
const MatrixVectorT& matrices, DimensionFn&& dimension)
290 std::size_t total = 0;
291 for (
const auto& matrix : matrices) {
292 total += dimension(matrix);
298 static std::size_t countRowEntries(
const Row& row)
300 return static_cast<std::size_t
>(std::distance(row.begin(), row.end()));
303 template<
class Row,
class Matrix,
class ColumnMapper>
304 static void assignRowValues(
const Row& row,
305 Matrix& mergedMatrix,
306 std::size_t mergedRow,
307 ColumnMapper&& mapColumn)
309 for (
auto colIt = row.begin(); colIt != row.end(); ++colIt) {
310 mergedMatrix[mergedRow][mapColumn(colIt.index())] = *colIt;
314 void fillBValues(
BMatrix& mergedMatrix)
const
316 std::size_t rowOffset = 0;
317 for (std::size_t well = 0; well < bMatrices_.size(); ++well) {
318 const auto& matrix = bMatrices_[well];
319 const auto& cells = wellCells_[well];
320 for (std::size_t row = 0; row < matrix.N(); ++row) {
321 assignRowValues(matrix[row], mergedMatrix, rowOffset + row,
322 [&cells](
auto localColumn) {
323 assert(cells[localColumn] >= 0);
324 return static_cast<std::size_t
>(cells[localColumn]);
327 rowOffset += matrix.N();
331 void fillCValues(
CMatrix& mergedMatrix)
const
333 std::size_t colOffset = 0;
334 for (std::size_t well = 0; well < cMatrices_.size(); ++well) {
335 const auto& matrix = cMatrices_[well];
336 const auto& cells = wellCells_[well];
337 for (std::size_t row = 0; row < matrix.N(); ++row) {
338 assert(cells[row] >= 0);
339 const auto cell =
static_cast<std::size_t
>(cells[row]);
340 assignRowValues(matrix[row], mergedMatrix, cell,
341 [colOffset](
auto localColumn) {
return colOffset + localColumn; });
343 colOffset += matrix.M();
347 void fillDValues(
DMatrix& mergedMatrix)
const
349 std::size_t rowOffset = 0;
350 for (
const auto& matrix : dMatrices_) {
351 for (std::size_t row = 0; row < matrix.N(); ++row) {
352 assignRowValues(matrix[row], mergedMatrix, rowOffset + row,
353 [rowOffset](
auto localColumn) {
return rowOffset + localColumn; });
355 rowOffset += matrix.N();
359 void mergeBMatrix(
BMatrix& mergedMatrix)
const
361 if (bMatrices_.empty()) {
362 initializeEmptyMatrix(mergedMatrix, 0, numResDofs_);
366 const auto totalRows = sumMatrixDimension(bMatrices_, [](
const auto& matrix) {
return matrix.N(); });
368 mergedMatrix.setSize(totalRows, numResDofs_);
369 mergedMatrix.setBuildMode(BMatrix::random);
371 std::size_t rowOffset = 0;
372 for (
const auto& matrix : bMatrices_) {
373 for (std::size_t row = 0; row < matrix.N(); ++row) {
374 mergedMatrix.setrowsize(rowOffset + row, countRowEntries(matrix[row]));
376 rowOffset += matrix.N();
378 mergedMatrix.endrowsizes();
381 for (std::size_t well = 0; well < bMatrices_.size(); ++well) {
382 const auto& matrix = bMatrices_[well];
383 const auto& cells = wellCells_[well];
384 for (std::size_t row = 0; row < matrix.N(); ++row) {
385 for (
auto colIt = matrix[row].begin(); colIt != matrix[row].end(); ++colIt) {
386 assert(cells[colIt.index()] >= 0);
387 mergedMatrix.addindex(rowOffset + row,
388 static_cast<std::size_t
>(cells[colIt.index()]));
391 rowOffset += matrix.N();
393 mergedMatrix.endindices();
395 fillBValues(mergedMatrix);
398 void mergeCMatrix(
CMatrix& mergedMatrix)
const
400 if (cMatrices_.empty()) {
401 initializeEmptyMatrix(mergedMatrix, numResDofs_, 0);
405 const auto totalCols = sumMatrixDimension(cMatrices_, [](
const auto& matrix) {
return matrix.M(); });
407 mergedMatrix.setSize(numResDofs_, totalCols);
408 mergedMatrix.setBuildMode(CMatrix::random);
410 std::vector<std::size_t> rowSizes(numResDofs_, 0);
411 for (std::size_t well = 0; well < cMatrices_.size(); ++well) {
412 const auto& matrix = cMatrices_[well];
413 const auto& cells = wellCells_[well];
414 for (std::size_t rowIdx = 0; rowIdx < matrix.N(); ++rowIdx) {
415 assert(cells[rowIdx] >= 0);
416 rowSizes[
static_cast<std::size_t
>(cells[rowIdx])] += countRowEntries(matrix[rowIdx]);
419 for (std::size_t row = 0; row < numResDofs_; ++row) {
420 mergedMatrix.setrowsize(row, rowSizes[row]);
422 mergedMatrix.endrowsizes();
424 std::size_t colOffset = 0;
425 for (std::size_t well = 0; well < cMatrices_.size(); ++well) {
426 const auto& matrix = cMatrices_[well];
427 const auto& cells = wellCells_[well];
428 for (std::size_t rowIdx = 0; rowIdx < matrix.N(); ++rowIdx) {
429 assert(cells[rowIdx] >= 0);
430 const auto cell =
static_cast<std::size_t
>(cells[rowIdx]);
431 for (
auto colIt = matrix[rowIdx].begin(); colIt != matrix[rowIdx].end(); ++colIt) {
432 mergedMatrix.addindex(cell, colOffset + colIt.index());
435 colOffset += matrix.M();
437 mergedMatrix.endindices();
439 fillCValues(mergedMatrix);
442 void mergeDMatrix(
DMatrix& mergedMatrix)
const
444 if (dMatrices_.empty()) {
445 initializeEmptyMatrix(mergedMatrix, 0, 0);
449 const auto totalSize = sumMatrixDimension(dMatrices_, [](
const auto& matrix) {
return matrix.N(); });
451 mergedMatrix.setSize(totalSize, totalSize);
452 mergedMatrix.setBuildMode(DMatrix::random);
454 std::size_t rowOffset = 0;
455 for (
const auto& matrix : dMatrices_) {
456 for (std::size_t rowIdx = 0; rowIdx < matrix.N(); ++rowIdx) {
457 mergedMatrix.setrowsize(rowOffset + rowIdx, countRowEntries(matrix[rowIdx]));
459 rowOffset += matrix.N();
461 mergedMatrix.endrowsizes();
464 for (
const auto& matrix : dMatrices_) {
465 for (std::size_t rowIdx = 0; rowIdx < matrix.N(); ++rowIdx) {
466 for (
auto colIt = matrix[rowIdx].begin(); colIt != matrix[rowIdx].end(); ++colIt) {
467 mergedMatrix.addindex(rowOffset + rowIdx, rowOffset + colIt.index());
470 rowOffset += matrix.N();
472 mergedMatrix.endindices();
474 fillDValues(mergedMatrix);
477 std::size_t numResDofs_;
478 const std::vector<BMatrix>& bMatrices_;
479 const std::vector<CMatrix>& cMatrices_;
480 const std::vector<DMatrix>& dMatrices_;
Definition: WellMatrixMerger.hpp:164
WellMatrixStructure buildStructure() const
Definition: WellMatrixMerger.hpp:214
bool hasSameStructure(const WellMatrixStructure &cachedStructure) const
Definition: WellMatrixMerger.hpp:184
WRMatrix< Scalar > BMatrix
Definition: WellMatrixMerger.hpp:166
void updateValues(BMatrix &mergedB, CMatrix &mergedC, DMatrix &mergedD) const
Definition: WellMatrixMerger.hpp:243
RWMatrix< Scalar > CMatrix
Definition: WellMatrixMerger.hpp:167
WellMatrixMerger(const std::size_t nResDofs, const std::vector< BMatrix > &bMatrices, const std::vector< CMatrix > &cMatrices, const std::vector< DMatrix > &dMatrices, const Opm::SparseTable< int > &wellCells)
Definition: WellMatrixMerger.hpp:170
WWMatrix< Scalar > DMatrix
Definition: WellMatrixMerger.hpp:168
void buildMatrices(BMatrix &mergedB, CMatrix &mergedC, DMatrix &mergedD) const
Definition: WellMatrixMerger.hpp:234
Definition: blackoilbioeffectsmodules.hh:45
Dune::BCRSMatrix< Dune::FieldMatrix< Scalar, numWellDofs, numWellDofs > > WWMatrix
Definition: SystemTypes.hpp:52
Dune::BCRSMatrix< Dune::FieldMatrix< Scalar, numResDofs, numWellDofs > > RWMatrix
Definition: SystemTypes.hpp:48
bool hasSameMatrixSparsity(const Matrix &matrix, const MatrixSparsityPattern &pattern)
Definition: WellMatrixMerger.hpp:113
MatrixSparsityPattern captureMatrixSparsity(const Matrix &matrix)
Definition: WellMatrixMerger.hpp:92
Dune::BCRSMatrix< Dune::FieldMatrix< Scalar, numWellDofs, numResDofs > > WRMatrix
Definition: SystemTypes.hpp:50
Definition: WellMatrixMerger.hpp:40
std::vector< int > columnIndices
Definition: WellMatrixMerger.hpp:44
bool operator!=(const MatrixSparsityPattern &other) const
Definition: WellMatrixMerger.hpp:54
std::size_t rows
Definition: WellMatrixMerger.hpp:41
bool operator==(const MatrixSparsityPattern &other) const
Definition: WellMatrixMerger.hpp:46
std::vector< std::size_t > rowOffsets
Definition: WellMatrixMerger.hpp:43
std::size_t cols
Definition: WellMatrixMerger.hpp:42
Definition: WellMatrixMerger.hpp:66
bool operator==(const WellMatrixStructure &other) const
Definition: WellMatrixMerger.hpp:74
bool operator!=(const WellMatrixStructure &other) const
Definition: WellMatrixMerger.hpp:84
std::vector< MatrixSparsityPattern > cPatterns
Definition: WellMatrixMerger.hpp:71
std::size_t numResDofs
Definition: WellMatrixMerger.hpp:67
Opm::SparseTable< int > wellCells
Definition: WellMatrixMerger.hpp:69
std::vector< MatrixSparsityPattern > dPatterns
Definition: WellMatrixMerger.hpp:72
std::vector< MatrixSparsityPattern > bPatterns
Definition: WellMatrixMerger.hpp:70
std::size_t totalWellBlocks
Definition: WellMatrixMerger.hpp:68