Iterative Solvers#

The solvers library comes with some iterative solver methods which target a linear system.

These solvers can be divided into two kinds of group. One is for symmetric linear system and another is for a non-symmetric system. Each solver uses largeMatrix and Vector as inputs and returns the result in a Vector.

The type of problem, real or complex, needs specified also as another input of a solver. In some cases, a solver can take advantage of a Preconditioner as an extra input to decrease the conditioner number of the system. A Preconditioner, which is also a LargeMatrix involved with matrix factorization, is only available in the type of SkylineStorage and CsStorage.

All solvers in the library are based on the class IterativeSolver, which provides some basic properties and methods. Specific iterative algorithms are implemented in the inherited class for two cases: with and without a preconditioner.

Figure made with TikZ

Figure made with TikZ

The IterativeSolver class#

As the base class of all other solver classes, the IterativeSolver provides some basic properties and methods for all descendants.

class IterativeSolver
{
  public:
    //! Constructor by name
    IterativeSolver(const string_t& name, number_t vb = 0);
    //! Constructor by type
    IterativeSolver(IterativeSolverType ist, number_t vb = 0);
    //! Full constructor without type
    IterativeSolver(const string_t& name, number_t maxOfIt, real_t eps, number_t vb = 0, bool prec = true);
    //! Full constructor without name
    IterativeSolver(IterativeSolverType ist, number_t maxOfIt, real_t eps, number_t vb = 0, bool prec = true);
    //! Full constructor
    IterativeSolver(const string_t& name, IterativeSolverType ist, number_t maxOfIt, real_t eps, number_t vb = 0, bool prec = true);

    //! Destructor
    virtual ~IterativeSolver();

    //! Iterative solver name for documentation purposes
    string_t name() { return name_; }
    //! Reset Solver
    void resetSolver();

   protected:
   //! Define a default value for the maximum number of iterations
   number_t maximumOfIterations(const size_t nbRows);
   ...
}

A solver object can be constructed in several ways: With default values or with user-input values.

Information of solver can be printed out with some auxiliary functions.

void printHeader(const size_t) const;
void printHeader(const size_t, const String&) const;
void printHeader(const size_t, const Real) const;
void printHeader(const size_t, const Number) const;
void printHeader(const size_t, const Number, const String&) const;
void printOutput() const;
void printIteration() const;

In order to avoid invalid cast from complex to real and vice versa, some inline functions are provided.

inline void assign(Real& x, const Real& y) { x = y; }
inline void assign(Complex& x, const Real& y) { x = y; }
inline void assign(Complex& x, const Complex& y) { x = y; }
inline void assign(Real& x, const Complex& y) { x = y.real(); }

See also

  • library= solvers,

  • header= IterativeSolver.hpp,

  • implementation= IterativeSolver.cpp,

  • test= test_BicgSolver.hpp, test_BicgStabSolver.hpp, test_CgSolver.hpp, test_CgsSolver.hpp, test_GmresSolver.hpp, test_QmrSolver.hpp, test_SorSolver.hpp, test_SsorSolver.hpp

  • header dep= Preconditioner.hpp, config.h, utils.h

The Preconditioner class#

In some cases, the rate of convergence of an iterative solver can increase as a result of preconditioning. A preconditioner is basically a special matrix which can be factorized. There exist several types of matrix-factorization for Preconditioner: LU, LDLt, LDL*, Diag and SOR. Because of constraints of factorizing, only matrices of SkylineStorage and CsStorage can be used as a preconditioner.

In detail, a preconditioner is based on a template class Mat, on which all the preconditioned-solver are processed.

template<class Mat>
class Preconditioner
{
 public:
  Mat* precondMatrix_p; // pointer to precondition matrix
 private:
  //! Type of preconditioner
  PreconditionerType type_;
  //! Relaxation parameter for SSOR preconditioners
  Real omega_;
 public:
  Preconditioner()
   : precondMatrix_p(0), type_(_noPreconditioner), omega_(0.)  { }

   Preconditioner(PreconditionerType pt, Mat& A, const Real w = 1.)
    : precondMatrix_p(&A), type_(pt), omega_(w)  { }

   Preconditioner(Mat& A, PreconditionerType pt, const Real w = 1.)
     : precondMatrix_p(&A), type_(pt), omega_(w)  {  }

   ~Preconditioner() {};
   //! Return type of preconditionner
   static String name(PreconditionerType pt)
   {
     String s("");
     switch ( pt )
     {
       case _lu:       s = "LU"; bre
       ak;
       case _ldlt:     s = "LDLt"; break;
       case _ldlStar:  s = "LDL*"; break;
       case _ssor:     s = "SSOR"; break;
       case _diag:     s = "Diagonal"; break;
        //case myPreconditioner: s = "User Supplied"; break;
       default: break;
     }
     return s;
  }
 ...

Hint

A preconditioner can only templated with a specific kind of matrix that can be decomposed. There are only two types of storage, with which matrix can be factorized: SkylineStorage with LU, LDLt, LDL* factorization; CsStorage with SOR and DIAG factorization.

There are several constructors:

Preconditioner()
 : precondMatrix_p(0), type_(_noPreconditioner), omega_(0.)  { }

Preconditioner(PreconditionerType pt, Mat& A, const Real w = 1.)
 : precondMatrix_p(&A), type_(pt), omega_(w)  {  }

Preconditioner(Mat& A, PreconditionerType pt, const Real w = 1.)
 : precondMatrix_p(&A), type_(pt), omega_(w)  {  }

The PreconditionerType is an enumeration.

enum PreconditionerType {_noPreconditioner, _lu, _ldlt, _ldlStar, _ssor, _diag, _myPreconditioner};

See also

  • library= solvers,

  • header= Preconditioner.hpp,

  • implementation= Preconditioner.cpp,

  • test= test_LargeMatrixSkylineStorage.cpp, test_LargeMatrixCsStorage.cpp

  • header dep= config.h, utils.h

Solvers#

Each solver class in the solvers library implements a specific iterative method to solve a linear system: A*X=B in two cases: Real or Complex. The algorithm of all solvers except SOR and SSOR can work with and without a Preconditioner. Each solver takes largeMatrix \(matA\) and Vector \(vecB\) as inputs and a Vector \(vecX\) as output whose value is initialized with the input Vector \(vecX0\). A solver without a preconditioner is invoked with the overloading operator():

template<class Mat, class VecB, class VecX>
VecX operator()(Mat& matA, VecB& vecB, VecX& vecX0, ValueType solType)

Meanwhile, solver with a preconditioner \(pc\) can be used with the call

template<class Mat, class VecB, class VecX, class Prec>
VecX operator()(Mat& matA, VecB& vecB, VecX& vecX0, Prec& pc, ValueType solType)

User must specify the type of solver solType, which can be _real or _complex. The algorithm corresponds to without-preconditioner solver

template<typename K, class Mat, class VecB, class VecX>
void algorithm(Mat& matA, VecB& vecB, VecX& vecX, VecX& vecR)

and to a preconditioned one

template<typename K, class Mat, class VecB, class VecX, class Prec>
void algorithm(Mat& matA, VecB& vecB, VecX& vecX, VecX& vecR, Prec& pc)

The BicgSolver class

This class implements the Biconjugate Gradient method to solve a linear system. There are several basic constructors calling IterativeSolver constructors

class BicgSolver : public IterativeSolver
{
 public:
  //! Default Constructor
  BicgSolver() : IterativeSolver(_bicg) {}
  //! Full constructor
  BicgSolver(real_t eps, number_t maxOfIt = defaultMaxIterations, number_t vb = 0)
  : IterativeSolver(_bicg, maxOfIt, eps, vb) {}

  //! contructors with key-value system
  BicgSolver(const Parameter& p1) : IterativeSolver(_bicg)
  {
    std::vector<Parameter> ps(1, p1);
    real_t omega=1.; number_t krylovDim=defaultKrylovDimension;
    IterativeSolverType ist=_bicg;
    buildSolverParams(ps, epsilon_, maxOfIterations_, omega, krylovDim, verboseLevel_, name_, ist);
  }
  BicgSolver(const Parameter& p1, const Parameter& p2) : IterativeSolver(_bicg)
  {
    std::vector<Parameter> ps(2);
    ps[0]=p1; ps[1]=p2;
    real_t omega=1.; number_t krylovDim=defaultKrylovDimension;
    IterativeSolverType ist=_bicg;
    buildSolverParams(ps, epsilon_, maxOfIterations_, omega, krylovDim, verboseLevel_, name_, ist);
  }
  BicgSolver(const Parameter& p1, const Parameter& p2, const Parameter& p3) : IterativeSolver(_bicg)
  {
    std::vector<Parameter> ps(3);
    ps[0]=p1; ps[1]=p2; ps[2]=p3;
    real_t omega=1.; number_t krylovDim=defaultKrylovDimension;
    IterativeSolverType ist=_bicg;
    buildSolverParams(ps, epsilon_, maxOfIterations_, omega, krylovDim, verboseLevel_, name_, ist);
  }
  ...
}

See also

  • library= solvers,

  • test= test_BicgSolver.cpp

  • header dep= IterativeSolver.hpp, Preconditioner.hpp

The BicgStabSolver class#

This class implements the Biconjugate Gradient Stabilized method to solve a linear system. There are several basic constructors calling IterativeSolver constructors

class BicgStabSolver : public IterativeSolver
{
  public:
   //! Default Constructor
   BicgStabSolver() : IterativeSolver(_bicgstab) {}
   //! Full Constructor
   BicgStabSolver(real_t eps, number_t maxOfIt = defaultMaxIterations, number_t vb = 0)
   : IterativeSolver(_bicgstab, maxOfIt, eps, vb) {}

   //! contructors with key-value system
   BicgStabSolver(const Parameter& p1) : IterativeSolver(_bicgstab)
   {
    std::vector<Parameter> ps(1, p1);
    real_t omega=1.; number_t krylovDim=defaultKrylovDimension;
    IterativeSolverType ist=_bicgstab;
    buildSolverParams(ps, epsilon_, maxOfIterations_, omega, krylovDim, verboseLevel_, name_, ist);
   }
   BicgStabSolver(const Parameter& p1, const Parameter& p2) : IterativeSolver(_bicgstab)
   {
    std::vector<Parameter> ps(2);
    ps[0]=p1; ps[1]=p2;
    real_t omega=1.; number_t krylovDim=defaultKrylovDimension;
    IterativeSolverType ist=_bicgstab;
    buildSolverParams(ps, epsilon_, maxOfIterations_, omega, krylovDim, verboseLevel_, name_, ist);
   }
   BicgStabSolver(const Parameter& p1, const Parameter& p2, const Parameter& p3) : IterativeSolver(_bicgstab)
   {
    std::vector<Parameter> ps(3);
    ps[0]=p1; ps[1]=p2; ps[2]=p3;
    real_t omega=1.; number_t krylovDim=defaultKrylovDimension;
    IterativeSolverType ist=_bicgstab;
    buildSolverParams(ps, epsilon_, maxOfIterations_, omega, krylovDim, verboseLevel_, name_, ist);
   }
  ...
}

See also

  • library= solvers,

  • test= test_BicgStabSolver.cpp

  • header dep= IterativeSolver.hpp, Preconditioner.hpp

The CgSolver class

This class implements the Conjugate Gradient method to solve a linear system. There are several basic constructors calling IterativeSolver constructors

class CgSolver : public IterativeSolver
{
 public:
  //! Default constructor
  CgSolver(): IterativeSolver(_cg) {}
  //! Full constructor
  CgSolver(real_t eps, number_t maxOfIt = defaultMaxIterations, number_t vb = 0)
  : IterativeSolver(_cg, maxOfIt, eps, vb) {}

  //! contructors with key-value system
  CgSolver(const Parameter& p1) : IterativeSolver(_cg)
  {
    std::vector<Parameter> ps(1, p1);
    real_t omega=1.; number_t krylovDim=defaultKrylovDimension;
    IterativeSolverType ist=_cg;
    buildSolverParams(ps, epsilon_, maxOfIterations_, omega, krylovDim, verboseLevel_, name_, ist);
  }
  CgSolver(const Parameter& p1, const Parameter& p2) : IterativeSolver(_cg)
  {
    std::vector<Parameter> ps(2);
    ps[0]=p1; ps[1]=p2;
    real_t omega=1.; number_t krylovDim=defaultKrylovDimension;
    IterativeSolverType ist=_cg;
    buildSolverParams(ps, epsilon_, maxOfIterations_, omega, krylovDim, verboseLevel_, name_, ist);
  }
  CgSolver(const Parameter& p1, const Parameter& p2, const Parameter& p3) : IterativeSolver(_cg)
  {
    std::vector<Parameter> ps(3);
    ps[0]=p1; ps[1]=p2; ps[2]=p3;
    real_t omega=1.; number_t krylovDim=defaultKrylovDimension;
    IterativeSolverType ist=_cg;
    buildSolverParams(ps, epsilon_, maxOfIterations_, omega, krylovDim, verboseLevel_, name_, ist);
  }
  ...
}

See also

  • library= solvers,

  • test= test_CgSolver.cpp

  • header dep= IterativeSolver.hpp, Preconditioner.hpp

The CgsSolver class#

This class implements the Conjugate Gradient Squared method to solve a linear system. There are several basic constructors calling IterativeSolver constructors

class CgsSolver : public IterativeSolver
{
 public:
  //! Default constructor
  CgsSolver()
    : IterativeSolver(_cgs) {}
  //! Full constructor
  CgsSolver(real_t eps, number_t maxOfIt = defaultMaxIterations, number_t vb = 0)
    : IterativeSolver(_cgs, maxOfIt, eps, vb) {}

  //! contructors with key-value system
  CgsSolver(const Parameter& p1) : IterativeSolver(_cgs)
  {
    std::vector<Parameter> ps(1, p1);
    real_t omega=1.; number_t krylovDim=defaultKrylovDimension;
    IterativeSolverType ist=_cgs;
    buildSolverParams(ps, epsilon_, maxOfIterations_, omega, krylovDim, verboseLevel_, name_, ist);
  }
  CgsSolver(const Parameter& p1, const Parameter& p2) : IterativeSolver(_cgs)
  {
    std::vector<Parameter> ps(2);
    ps[0]=p1; ps[1]=p2;
    real_t omega=1.; number_t krylovDim=defaultKrylovDimension;
    IterativeSolverType ist=_cgs;
    buildSolverParams(ps, epsilon_, maxOfIterations_, omega, krylovDim, verboseLevel_, name_, ist);
  }
  CgsSolver(const Parameter& p1, const Parameter& p2, const Parameter& p3) : IterativeSolver(_cgs)
  {
    std::vector<Parameter> ps(3);
    ps[0]=p1; ps[1]=p2; ps[2]=p3;
    real_t omega=1.; number_t krylovDim=defaultKrylovDimension;
    IterativeSolverType ist=_cgs;
    buildSolverParams(ps, epsilon_, maxOfIterations_, omega, krylovDim, verboseLevel_, name_, ist);
  }
  ...
}

See also

  • library= solvers,

  • test= test_CgsSolver.cpp

  • header dep= IterativeSolver.hpp, Preconditioner.H2-approximation

The GmresSolver class

This class implements the Generalized Minimal Residual method to solve a linear system. Different from other solvers, the GmresSolver has more constructors: user can specify the Krylov dimension in the constructor.

class GmresSolver : public IterativeSolver
{
 private:
  number_t krylovDim_;  //!< Dimension of Krylov space

 public:
  //! Constructor with Krylov dimension
  GmresSolver(number_t kd=defaultKrylovDimension)
    : IterativeSolver(_gmres, defaultMaxIterations, theDefaultConvergenceThreshold),
      krylovDim_(kd) {}
  //! Full constructor
  GmresSolver(number_t kd, real_t eps, number_t maxOfIt = defaultMaxIterations, number_t vb = 0)
  : IterativeSolver(_gmres, maxOfIt, eps, vb), krylovDim_(kd) {}

  //! contructors with key-value system
  GmresSolver(const Parameter& p1) : IterativeSolver(_gmres)
  {
    std::vector<Parameter> ps(1, p1);
    real_t omega=1.;
    IterativeSolverType ist=_gmres;
    buildSolverParams(ps, epsilon_, maxOfIterations_, omega, krylovDim_, verboseLevel_, name_, ist);
  }
  GmresSolver(const Parameter& p1, const Parameter& p2) : IterativeSolver(_gmres)
  {
    std::vector<Parameter> ps(2);
    ps[0]=p1; ps[1]=p2;
    real_t omega=1.;
    IterativeSolverType ist=_gmres;
    buildSolverParams(ps, epsilon_, maxOfIterations_, omega, krylovDim_, verboseLevel_, name_, ist);
  }
  GmresSolver(const Parameter& p1, const Parameter& p2, const Parameter& p3) : IterativeSolver(_gmres)
  {
    std::vector<Parameter> ps(3);
    ps[0]=p1; ps[1]=p2; ps[2]=p3;
    real_t omega=1.;
    IterativeSolverType ist=_gmres;
    buildSolverParams(ps, epsilon_, maxOfIterations_, omega, krylovDim_, verboseLevel_, name_, ist);
  }
  GmresSolver(const Parameter& p1, const Parameter& p2, const Parameter& p3, const Parameter& p4) : IterativeSolver(_gmres)
  {
    std::vector<Parameter> ps(4);
    ps[0]=p1; ps[1]=p2; ps[2]=p3; ps[3]=p4;
    real_t omega=1.;
    IterativeSolverType ist=_gmres;
    buildSolverParams(ps, epsilon_, maxOfIterations_, omega, krylovDim_, verboseLevel_, name_, ist);
  }
  ...
}

See also

  • library= solvers,

  • test= test_GmresSolver.cpp

  • header dep= IterativeSolver.hpp, Preconditioner.H2-approximation

The QmrSolver class#

This class implements the Quasi-Minimal Residual method to solve a linear system. There are several basic constructors calling IterativeSolver constructors

class QmrSolver : public IterativeSolver
{
 public:
  //! Constructor
  QmrSolver()
    : IterativeSolver(_qmr) {}
  //! Full Constructor
  QmrSolver(real_t eps, number_t maxOfIt = defaultMaxIterations, number_t vb = 0)
  : IterativeSolver(_qmr, maxOfIt, eps, vb) {}

  //! contructors with key-value system
  QmrSolver(const Parameter& p1) : IterativeSolver(_qmr)
  {
    std::vector<Parameter> ps(1, p1);
    real_t omega=1.; number_t krylovDim=defaultKrylovDimension;
    IterativeSolverType ist=_qmr;
    buildSolverParams(ps, epsilon_, maxOfIterations_, omega, krylovDim, verboseLevel_, name_, ist);
  }
  QmrSolver(const Parameter& p1, const Parameter& p2) : IterativeSolver(_qmr)
  {
    std::vector<Parameter> ps(2);
    ps[0]=p1; ps[1]=p2;
    real_t omega=1.; number_t krylovDim=defaultKrylovDimension;
    IterativeSolverType ist=_qmr;
    buildSolverParams(ps, epsilon_, maxOfIterations_, omega, krylovDim, verboseLevel_, name_, ist);
  }
  QmrSolver(const Parameter& p1, const Parameter& p2, const Parameter& p3) : IterativeSolver(_qmr)
  {
    std::vector<Parameter> ps(3);
    ps[0]=p1; ps[1]=p2; ps[2]=p3;
    real_t omega=1.; number_t krylovDim=defaultKrylovDimension;
    IterativeSolverType ist=_qmr;
    buildSolverParams(ps, epsilon_, maxOfIterations_, omega, krylovDim, verboseLevel_, name_, ist);
  }
  ...
}

See also

  • library= solvers,

  • test= test_QmrSolver.cpp

  • header dep= IterativeSolver.hpp, Preconditioner.H2-approximation

The SorSolver class#

This class implements the Successive Over Relaxation method to solve a linear system. For this solver, user can have more choices to specify the relaxation factor \(omega\) in the constructor. Different from other solvers above, SorSolver doesn’t work with a preconditioner.

class SorSolver : public IterativeSolver
{
 private:
  real_t omega_;  //!< relaxation factor of SOR method

 public:
  //! Constructor with omega
  SorSolver(real_t w=1.) : IterativeSolver(_sor), omega_(w) {}
  //! Full constructor
  SorSolver(real_t w, real_t eps, number_t maxOfIt = defaultMaxIterations, number_t vb = 0)
  : IterativeSolver(_sor, maxOfIt, eps, vb), omega_(w) {}

  //! contructors with key-value system
  SorSolver(const Parameter& p1) : IterativeSolver(_sor)
  {
    std::vector<Parameter> ps(1, p1);
    number_t krylovDim=defaultKrylovDimension;
    IterativeSolverType ist=_sor;
    buildSolverParams(ps, epsilon_, maxOfIterations_, omega_, krylovDim, verboseLevel_, name_, ist);
  }
  SorSolver(const Parameter& p1, const Parameter& p2) : IterativeSolver(_sor)
  {
    std::vector<Parameter> ps(2);
    ps[0]=p1; ps[1]=p2;
    number_t krylovDim=defaultKrylovDimension;
    IterativeSolverType ist=_sor;
    buildSolverParams(ps, epsilon_, maxOfIterations_, omega_, krylovDim, verboseLevel_, name_, ist);
  }
  SorSolver(const Parameter& p1, const Parameter& p2, const Parameter& p3) : IterativeSolver(_sor)
  {
    std::vector<Parameter> ps(3);
    ps[0]=p1; ps[1]=p2; ps[2]=p3;
    number_t krylovDim=defaultKrylovDimension;
    IterativeSolverType ist=_sor;
    buildSolverParams(ps, epsilon_, maxOfIterations_, omega_, krylovDim, verboseLevel_, name_, ist);
  }
  SorSolver(const Parameter& p1, const Parameter& p2, const Parameter& p3, const Parameter& p4) : IterativeSolver(_sor)
  {
    std::vector<Parameter> ps(4);
    ps[0]=p1; ps[1]=p2; ps[2]=p3; ps[3]=p4;
    number_t krylovDim=defaultKrylovDimension;
    IterativeSolverType ist=_sor;
    buildSolverParams(ps, epsilon_, maxOfIterations_, omega_, krylovDim, verboseLevel_, name_, ist);
  }
  ...
}

See also

  • library= solvers,

  • test= test_SorSolver.cpp

  • header dep= IterativeSolver.hpp, Preconditioner.H2-approximation

The SsorSolver class#

This class implements the Symmetric Successive Over Relaxation method to solve a linear system. Like SorSolver, the SsorSolver only works without a preconditioner and user can specify the relaxation factor \(omega\) in the constructor.

class SsorSolver : public IterativeSolver
{
 private:
  real_t omega_;  //!< relaxation factor of SOR method

 public:
  //! Constructor with omega
  SsorSolver(real_t w=1.) : IterativeSolver(_ssor), omega_(w) {}
  //! Full constructor
  SsorSolver(real_t w, real_t eps, number_t maxOfIt = defaultMaxIterations, number_t vb = 0)
  : IterativeSolver(_ssor, maxOfIt, eps, vb), omega_(w) {}

  //! contructors with key-value system
  SsorSolver(const Parameter& p1) : IterativeSolver(_ssor)
  {
    std::vector<Parameter> ps(1, p1);
    number_t krylovDim=defaultKrylovDimension;
    IterativeSolverType ist=_ssor;
    buildSolverParams(ps, epsilon_, maxOfIterations_, omega_, krylovDim, verboseLevel_, name_, ist);
  }
  SsorSolver(const Parameter& p1, const Parameter& p2) : IterativeSolver(_ssor)
  {
    std::vector<Parameter> ps(2);
    ps[0]=p1; ps[1]=p2;
    number_t krylovDim=defaultKrylovDimension;
    IterativeSolverType ist=_ssor;
    buildSolverParams(ps, epsilon_, maxOfIterations_, omega_, krylovDim, verboseLevel_, name_, ist);
  }
  SsorSolver(const Parameter& p1, const Parameter& p2, const Parameter& p3) : IterativeSolver(_ssor)
  {
    std::vector<Parameter> ps(3);
    ps[0]=p1; ps[1]=p2; ps[2]=p3;
    number_t krylovDim=defaultKrylovDimension;
    IterativeSolverType ist=_ssor;
    buildSolverParams(ps, epsilon_, maxOfIterations_, omega_, krylovDim, verboseLevel_, name_, ist);
  }
  SsorSolver(const Parameter& p1, const Parameter& p2, const Parameter& p3, const Parameter& p4) : IterativeSolver(_ssor)
  {
    std::vector<Parameter> ps(4);
    ps[0]=p1; ps[1]=p2; ps[2]=p3; ps[3]=p4;
    number_t krylovDim=defaultKrylovDimension;
    IterativeSolverType ist=_ssor;
    buildSolverParams(ps, epsilon_, maxOfIterations_, omega_, krylovDim, verboseLevel_, name_, ist);
  }
  ...
}

See also

  • library= solvers,

  • test= test_SsorSolver.cpp

  • header dep= IterativeSolver.hpp, Preconditioner.H2-approximation