// This is an adaptation of step-20, so the main class and the data types
// are nearly the same as used there. The only difference is that we have an
// additional member <code>preconditioner_matrix</code>, that is used for
- // preconditioning the Schur complement, and a corresponding sparsity pattern
- // <code>preconditioner_sparsity_pattern</code>.
+ // preconditioning the Schur complement, and a corresponding sparsity
+ // pattern <code>preconditioner_sparsity_pattern</code>. In addition,
+ // instead of relying on LinearOperator, we implement our own InverseMatrix
+ // class.
+ //
// In this example we also use adaptive grid refinement, which is handled
// in analogy to step-6. According to the discussion in the introduction,
// we are also going to use the AffineConstraints object for implementing
// introduction. Here, we create the respective objects that will be used.
// @sect4{The <code>InverseMatrix</code> class template}
-
// The <code>InverseMatrix</code> class represents the data structure for an
- // inverse matrix. It is derived from the one in step-20. The only
- // difference is that we now do include a preconditioner to the matrix since
- // we will apply this class to different kinds of matrices that will require
- // different preconditioners (in step-20 we did not use a preconditioner in
- // this class at all). The types of matrix and preconditioner are passed to
- // this class via template parameters, and matrix and preconditioner objects
- // of these types will then be passed to the constructor when an
+ // inverse matrix. Unlike step-20, we implement this with a class instead of
+ // the helper function inverse_linear_operator() we will apply this class to
+ // different kinds of matrices that will require different preconditioners
+ // (in step-20 we only used a non-identity preconditioner for the mass
+ // matrix). The types of matrix and preconditioner are passed to this class
+ // via template parameters, and matrix and preconditioner objects of these
+ // types will then be passed to the constructor when an
// <code>InverseMatrix</code> object is created. The member function
- // <code>vmult</code> is, as in step-20, a multiplication with a vector,
- // obtained by solving a linear system:
+ // <code>vmult</code> is obtained by solving a linear system:
template <class MatrixType, class PreconditionerType>
class InverseMatrix : public Subscriptor
{
// of (templated) class <code>PreconditionerType</code>.
//
// In a minor deviation from the implementation of the same class in
- // step-22 (and step-20), we make the <code>vmult</code> function take any
+ // step-22, we make the <code>vmult</code> function take any
// kind of vector type (it will yield compiler errors, however, if the
// matrix does not allow a matrix-vector product with this kind of
// vector).
// This class exposes the action of applying the inverse of a giving
// matrix via the function InverseMatrix::vmult(). Internally, the
// inverse is not formed explicitly. Instead, a linear solver with CG
- // is performed. This class extends the InverseMatrix class in step-20
+ // is performed. This class extends the InverseMatrix class in step-22
// with an option to specify a preconditioner, and to allow for different
- // vector types
- // in the vmult function.
+ // vector types in the vmult function.
template <class Matrix, class Preconditioner>
class InverseMatrix : public Subscriptor
{