ddemidov / amgcl

C++ library for solving large sparse linear systems with algebraic multigrid method
http://amgcl.readthedocs.org/
MIT License
728 stars 111 forks source link

Improving AMG settings #91

Closed klausbu closed 3 years ago

klausbu commented 6 years ago

These are the characteristics of an AMG implementation highly optimized to solve the p equation matrix resulting from external flow problems (CFD):

  Characteristics:
  - Requires positive definite, diagonally dominant matrix.
  - Agglomeration algorithm: selectable and optionally cached.
  - Restriction operator: summation.
  - Prolongation operator: injection.
  - Smoother: Gauss-Seidel.
  - Coarse matrix creation: central coefficient: summation of fine grid
    central coefficients with the removal of intra-cluster face;
    off-diagonal coefficient: summation of off-diagonal faces.
  - Coarse matrix scaling: performed by correction scaling, using steepest
    descent optimisation.
  - Type of cycle: V-cycle with optional pre-smoothing.
  - Coarsest-level matrix solved using PCG or PBiCGStab.

Based on this, is there a way to improve the following settings:

typedef amgcl::make_solver<
    amgcl::amg<
        Backend,
        amgcl::runtime::coarsening::wrapper,
        amgcl::runtime::relaxation::wrapper
        >,
    amgcl::runtime::solver::wrapper<Backend>
    > Solver;

    boost::property_tree::ptree prm;

    prm.put("solver.type", "cg");
    prm.put("solver.tol", tolerance_);
    //prm.put("solver.abstol", relTol_);
    prm.put("solver.maxiter", 100);
    prm.put("precond.coarsening.type", "smoothed_aggregation");
    prm.put("precond.relax.type", "ilu0");
ddemidov commented 6 years ago

Interesting. Do you have a paper with more details?

  • Agglomeration algorithm: selectable and optionally cached.

Not sure what this means.

  • Restriction operator: summation.
  • Prolongation operator: injection.

This seems like a very simple strategy, so I would guess a smoothed_aggregation (prm.put("precond.coarsening.type", "smoothed_aggregation")) or non-smoothed aggregation (prm.put("precond.coarsening.type", "aggregation")) should work equally well

  • Smoother: Gauss-Seidel.

prm.put("precond.relax.type", "gauss_seidel"), although ilu0 should give you similar results.

  • Coarse matrix creation: central coefficient: summation of fine grid central coefficients with the removal of intra-cluster face; off-diagonal coefficient: summation of off-diagonal faces.
  • Coarse matrix scaling: performed by correction scaling, using steepest descent optimisation.

I don't know what these mean.

  • Type of cycle: V-cycle with optional pre-smoothing.

You get this is by default, and you can control the number of pre- and post- smoothing steps with 'precond.npre' and 'precond.npost'

  • Coarsest-level matrix solved using PCG or PBiCGStab.

Do you know why is this required? If the problem is singular, or is defined up to a constant, then you could use smoothing at the coarsest level insted of the default direct solve. To do that you prm.put("precond.direct_coarse", false) (also see https://github.com/ddemidov/amgcl/issues/31#issuecomment-251355550).

What problem exactly are you trying to solve? If this is a Navier-Stokes system, you could use schur_pressure_correction preconditioner. It is a two-step field-split-type preconditioner that treats pressure and velocity unknowns differently. See examples/schur_pressure_correction.cpp for an example, and https://amgcl.readthedocs.io/en/latest/benchmarks.html#d-navier-stokes-problem for some results.