Julia interface to hypre linear solvers (https://github.com/hypre-space/hypre)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

3.4 KiB

Solvers and preconditioners

HYPRE.jl wraps most of HYPREs ParCSR solvers and preconditioners.

The synopsis for creating and using HYPRE.jl's solver wrappers is the same for all solvers:

  1. Set up the linear system (see Matrix/vector representation)
  2. (Optional) Configure a preconditioner
  3. Configure a solver
  4. Use HYPRE.solve or HYPRE.solve! to solve the system

Here is the corresponding pseudo-code:

# 1. Setup up linear system
A = HYPREMatrix(...)
b = HYPREVector(...)

# 2. Configure a preconditioner
precond = HYPRESolver(; settings...)

# 3. Configure a solver
solver = HYPRESolver(; Precond = precond, settings...)

# 4. Solve the system
x = HYPRE.solve(solver, A, b)

The following solvers/preconditioners are currently available:

Solver configuration

Settings are passed as keyword arguments, with the names matching directly to HYPRE_SolverSet* calls from the HYPRE C API (see example below). Most settings are passed directly to HYPRE, for example Tol = 1e-9 would be passed directly to HYPRE_SolverSetTol for the correponding solver.

Setting a preconditioner can be done by passing a HYPRESolver directly with the Precond keyword argument, without any need to also pass the corresponding HYPRE_SolverSetup and HYPRE_SolverSolve as must be done in the C API. In addition, solvers that have required settings when used as a preconditioner will have those applied automatically.

HYPRE.jl adds finalizers to the solvers, which takes care of calling the their respective HYPRE_SolverDestroy function when the solver is garbage collected.

Example: Conjugate gradient with algebraic multigrid preconditioner

Here is an example of creating a PCG (conjugate gradient) solver with BoomerAMG (algebraic multigrid) as preconditioner:

# Setup up linear system
A = HYPREMatrix(...)
b = HYPREVector(...)

# Preconditioner
precond = HYPRE.BoomerAMG(; RelaxType = 6, CoarsenType = 6)

# Solver
solver = HYPRE.PCG(; MaxIter = 1000, Tol = 1e-9, Precond = precond)

# Solve
x = HYPRE.solve(solver, A, b)

Note that Tol = 0.0 and MaxIter = 1 are required settings when using BoomerAMG as a preconditioner. These settings are added automatically since it is passed as a preconditioner to the PCG solver.

!!! not "Corresponding C code" For comparison between the APIs, here is the corresponding C code for setting up the solver above: ```c /* Setup linear system */ HYPRE_IJMatrix A; HYPRE_IJVector b, x;

/* Preconditioner */
HYPRE_Solver precond;
HYPRE_BoomerAMGCreate(&precond);
HYPRE_BoomerAMGSetCoarsenType(precond, 6);
HYPRE_BoomerAMGSetRelaxType(precond, 6);
HYPRE_BoomerAMGSetTol(precond, 0.0);
HYPRE_BoomerAMGSetMaxIter(precond, 1);

/* Solver */
HYPRE_Solver solver;
HYPRE_ParCSRPCGCreate(MPI_COMM_WORLD, &solver);
HYPRE_PCGSetMaxIter(solver, 1000);

/* Add preconditioner */
HYPRE_PCGSetPrecond(solver, (HYPRE_PtrToSolverFcn) HYPRE_BoomerAMGSolve,
                            (HYPRE_PtrToSolverFcn) HYPRE_BoomerAMGSetup, precond);

/* Solve */
HYPRE_ParCSRPCGSetup(solver, A, b, x);
HYPRE_ParCSRPCGSolve(solver, A, b, x);
```