UpwindTransportSolver.hpp File Reference
#include <opm/common/utility/SparseTable.hpp>
#include <opm/simulators/utils/Tarjan.hpp>
#include <algorithm>
#include <array>
#include <cmath>
#include <cstddef>
#include <span>
#include <stdexcept>
#include <string>
#include <utility>
#include <vector>
Include dependency graph for UpwindTransportSolver.hpp:

Go to the source code of this file.

Classes

struct  Opm::UpwindTransportSettings
 Settings of solveReordered(). More...
 
struct  Opm::UpwindTransportStatistics
 Statistics of a solveReordered() call. More...
 
class  Opm::detail::MatrixCoefficients< Matrix >
 The coefficients of solveReordered(), from a sparse block matrix. More...
 
class  Opm::detail::ReorderedSystem< Coefficients, Vectors >
 The system of solveReordered() and the work arrays for solving it. More...
 

Namespaces

namespace  Opm
 
namespace  Opm::detail
 

Functions

template<class Scalar >
void Opm::detail::solveDenseSystem (std::vector< Scalar > &a, std::vector< Scalar > &b, std::size_t m, std::size_t numRhs)
 Solve a dense system a x = b by Gaussian elimination with partial pivoting. More...
 
template<class Block >
bool Opm::detail::isNonzeroBlock (const Block &block)
 Whether any entry of a block is nonzero. NaN counts as nonzero, so that it is rejected by MatrixCoefficients. More...
 
template<class Block >
bool Opm::detail::isFiniteBlock (const Block &block)
 Whether all entries of a block are finite. More...
 
template<class Matrix , class Function >
void Opm::detail::forEachNonzeroCoupling (const Matrix &matrix, Function &&f)
 Call a function for every nonzero off-diagonal block of a sparse block matrix. More...
 
template<class Matrix , class Vectors >
UpwindTransportStatistics Opm::solveReordered (const Matrix &matrix, const Vectors &rhs, Vectors &x, const UpwindTransportSettings &settings={})
 Solve the block system A x_q = b_q described in the file comment. More...
 

Detailed Description

Solver for the linear system of an implicit upwind transport scheme, cell by cell in the order of the flow (a "reordering" solver).

Opm::solveReordered() solves A x_q = b_q for an assembled sparse matrix A with square N x N blocks, e.g. a Dune::BCRSMatrix, and all right-hand sides together. Row r depends on the cells c with a nonzero off-diagonal block A[r][c], i.e. its upwind neighbours; blocks that are stored but zero are ignored.

The cells are ordered with Opm::tarjan(), so every component only needs values that are already final. A single cell is solved with its diagonal block; the cells of a flow loop depend on each other and are solved directly if the loop is small, by block Gauss-Seidel otherwise.

For an M-matrix, as from an upwind scheme with storage, the solution is non-negative for non-negative rhs and Gauss-Seidel converges. Reordering pays off when the matrix is nearly triangular, as for pure advection; with diffusion or conduction the whole domain becomes one loop.