SpECTRE  v2024.04.12
LinearSolver::Serial::ExplicitInverse< LinearSolverRegistrars > Class Template Reference

Linear solver that builds a matrix representation of the linear operator and inverts it directly. More...

#include <ExplicitInverse.hpp>

Classes

struct  WriteMatrixToFile
 

Public Types

using options = tmpl::list< WriteMatrixToFile >
 
- Public Types inherited from LinearSolver::Serial::LinearSolver< tmpl::list< Registrars::ExplicitInverse > >
using registrars = tmpl::list< Registrars::ExplicitInverse >
 
using creatable_classes = Registration::registrants< tmpl::list< Registrars::ExplicitInverse > >
 

Public Member Functions

 ExplicitInverse (const ExplicitInverse &)=default
 
ExplicitInverseoperator= (const ExplicitInverse &)=default
 
 ExplicitInverse (ExplicitInverse &&)=default
 
ExplicitInverseoperator= (ExplicitInverse &&)=default
 
 ExplicitInverse (std::optional< std::string > matrix_filename=std::nullopt)
 
template<typename LinearOperator , typename VarsType , typename SourceType , typename... OperatorArgs>
Convergence::HasConverged solve (gsl::not_null< VarsType * > solution, const LinearOperator &linear_operator, const SourceType &source, const std::tuple< OperatorArgs... > &operator_args=std::tuple{}) const
 Solve the equation \(Ax=b\) by explicitly constructing the operator matrix \(A\) and its inverse. The first solve is computationally expensive and successive solves are cheap. More...
 
void reset () override
 Flags the operator to require re-initialization. No memory is released. Call this function to rebuild the solver when the operator changed. More...
 
size_t size () const
 Size of the operator. The stored matrix will have size^2 entries.
 
const blaze::DynamicMatrix< double, blaze::columnMajor > & matrix_representation () const
 The matrix representation of the solver. This matrix approximates the inverse of the subdomain operator.
 
void pup (PUP::er &p) override
 
std::unique_ptr< Baseget_clone () const override
 
template<typename LinearOperator , typename VarsType , typename SourceType , typename... OperatorArgs>
Convergence::HasConverged solve (const gsl::not_null< VarsType * > solution, const LinearOperator &linear_operator, const SourceType &source, const std::tuple< OperatorArgs... > &operator_args) const
 
- Public Member Functions inherited from LinearSolver::Serial::LinearSolver< tmpl::list< Registrars::ExplicitInverse > >
virtual std::unique_ptr< LinearSolver< tmpl::list< Registrars::ExplicitInverse > > > get_clone () const=0
 
Convergence::HasConverged solve (gsl::not_null< VarsType * > initial_guess_in_solution_out, const LinearOperator &linear_operator, const SourceType &source, const std::tuple< OperatorArgs... > &operator_args, Args &&... args) const
 Solve the linear equation \(Ax=b\) where \(A\) is the linear_operator and \(b\) is the source. More...
 
Convergence::HasConverged solve (const gsl::not_null< VarsType * > initial_guess_in_solution_out, const LinearOperator &linear_operator, const SourceType &source, const std::tuple< OperatorArgs... > &operator_args, Args &&... args) const
 
virtual void reset ()=0
 Discard caches from previous solves. Use before solving a different linear operator. More...
 

Static Public Attributes

static constexpr Options::String help
 

Detailed Description

template<typename LinearSolverRegistrars = tmpl::list<Registrars::ExplicitInverse>>
class LinearSolver::Serial::ExplicitInverse< 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.

Member Function Documentation

◆ get_clone()

template<typename LinearSolverRegistrars = tmpl::list<Registrars::ExplicitInverse>>
std::unique_ptr< Base > LinearSolver::Serial::ExplicitInverse< LinearSolverRegistrars >::get_clone ( ) const
inlineoverridevirtual

◆ reset()

template<typename LinearSolverRegistrars = tmpl::list<Registrars::ExplicitInverse>>
void LinearSolver::Serial::ExplicitInverse< LinearSolverRegistrars >::reset ( )
inlineoverridevirtual

Flags the operator to require re-initialization. No memory is released. Call this function to rebuild the solver when the operator changed.

Implements LinearSolver::Serial::LinearSolver< tmpl::list< Registrars::ExplicitInverse > >.

◆ solve()

template<typename LinearSolverRegistrars = tmpl::list<Registrars::ExplicitInverse>>
template<typename LinearOperator , typename VarsType , typename SourceType , typename... OperatorArgs>
Convergence::HasConverged LinearSolver::Serial::ExplicitInverse< LinearSolverRegistrars >::solve ( gsl::not_null< VarsType * >  solution,
const LinearOperator &  linear_operator,
const SourceType &  source,
const std::tuple< OperatorArgs... > &  operator_args = std::tuple{} 
) const

Solve the equation \(Ax=b\) by explicitly constructing the operator matrix \(A\) 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.

Member Data Documentation

◆ help

template<typename LinearSolverRegistrars = tmpl::list<Registrars::ExplicitInverse>>
constexpr Options::String LinearSolver::Serial::ExplicitInverse< LinearSolverRegistrars >::help
staticconstexpr
Initial value:
=
"Build a matrix representation of the linear operator and invert it "
"directly. This means that the first solve has a large initialization "
"cost, but all subsequent solves converge immediately."

The documentation for this class was generated from the following file: