mirror of https://github.com/fredrikekre/HYPRE.jl
3 changed files with 87 additions and 2 deletions
@ -0,0 +1,84 @@ |
|||||||
|
# Solvers and preconditioners |
||||||
|
|
||||||
|
HYPRE.jl wraps most of HYPREs [ParCSR solvers and |
||||||
|
preconditioners](https://hypre.readthedocs.io/en/latest/api-sol-parcsr.html). |
||||||
|
|
||||||
|
The synopsis for HYPRE.jl's wrappers is the same for all solvers: |
||||||
|
|
||||||
|
```julia |
||||||
|
# Setup up linear system (see previous section) |
||||||
|
A = HYPREMatrix(...) |
||||||
|
b = HYPREVector(...) |
||||||
|
|
||||||
|
# Create a solver |
||||||
|
solver = HYPRESolver(; settings...) |
||||||
|
|
||||||
|
# Solve A x = b |
||||||
|
x = HYPRE.solve(solver, A, b) |
||||||
|
``` |
||||||
|
|
||||||
|
Settings are passed as keyword arguments, with the names matching directly to |
||||||
|
`HYPRE_SolverSetXXX` 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: |
||||||
|
|
||||||
|
```julia |
||||||
|
# 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, 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); |
||||||
|
``` |
||||||
Loading…
Reference in new issue