Linear solver that builds a matrix representation of the linear operator and inverts it directly.
More...
template<typename ValueType, typename LinearSolverRegistrars = tmpl::list<Registrars::ExplicitInverse<ValueType>>>
class LinearSolver::Serial::ExplicitInverse< ValueType, LinearSolverRegistrars >
Linear solver that builds a matrix representation of the linear operator and inverts it directly.
This solver first constructs an explicit matrix representation by "sniffing
out" the operator, i.e. feeding it with unit vectors, and then directly inverts the matrix. The result is an operator that solves the linear problem in a single step. This means that each element has a large initialization cost, but all successive solves converge immediately.
- Advice on using this linear solver:
- This solver is entirely agnostic to the structure of the linear operator. It is usually better to implement a linear solver that is specialized for your linear operator to take advantage of its properties. For example, if the operator has a tensor-product structure, the linear solver might take advantage of that. Only use this solver if no alternatives are available and if you have verified that it speeds up your solves.
- Since this linear solver stores the full inverse operator matrix it can have significant memory demands. For example, an operator representing a 3D first-order Elasticity system (9 variables) discretized on 12 grid points per dimension requires ca. 2GB of memory (per element) to store the matrix, scaling quadratically with the number of variables and with a power of 6 with the number of grid points per dimension. Therefore, make sure to distribute the elements on a sufficient number of nodes to meet the memory requirements.
- This linear solver can be
reset()
when the operator changes (e.g. in each nonlinear-solver iteration). However, when using this solver as preconditioner it can be advantageous to avoid the reset and the corresponding cost of re-building the matrix and its inverse if the operator only changes "a little". In that case the preconditioner solves subdomain problems only approximately, but possibly still sufficiently to provide effective preconditioning.
template<typename ValueType , typename LinearSolverRegistrars = tmpl::list<Registrars::ExplicitInverse<ValueType>>>
template<typename LinearOperator , typename VarsType , typename SourceType , typename... OperatorArgs>
Solve the equation by explicitly constructing the operator matrix and its inverse. The first solve is computationally expensive and successive solves are cheap.
Building a matrix representation of the linear_operator
requires iterating over the SourceType
(which is also the type returned by the linear_operator
) in a consistent way. This can be non-trivial for heterogeneous data structures because it requires they define a data ordering. Specifically, the SourceType
must have a size()
function as well as begin()
and end()
iterators that point into the data. If the iterators have a reset()
function it is used to avoid repeatedly re-creating the begin()
iterator. The reset()
function must not invalidate the end()
iterator.