Browse Source

Add ParaSails preconditioner.

pull/5/head
Fredrik Ekre 3 years ago
parent
commit
9eba04500e
  1. 1
      gen/solver_options.jl
  2. 21
      src/solver_options.jl
  3. 27
      src/solvers.jl
  4. 24
      test/runtests.jl

1
gen/solver_options.jl

@ -57,5 +57,6 @@ open(joinpath(@__DIR__, "..", "src", "solver_options.jl"), "w") do io
generate_options(io, "BoomerAMG", "HYPRE_BoomerAMGSet") generate_options(io, "BoomerAMG", "HYPRE_BoomerAMGSet")
# generate_options(io, "FSAI", "HYPRE_FSAISet") # generate_options(io, "FSAI", "HYPRE_FSAISet")
generate_options(io, "GMRES", "HYPRE_ParCSRGMRESSet", "HYPRE_GMRESSet") generate_options(io, "GMRES", "HYPRE_ParCSRGMRESSet", "HYPRE_GMRESSet")
generate_options(io, "ParaSails", "HYPRE_ParCSRParaSailsSet", "HYPRE_ParaSailsSet")
generate_options(io, "PCG", "HYPRE_ParCSRPCGSet", "HYPRE_PCGSet") generate_options(io, "PCG", "HYPRE_ParCSRPCGSet", "HYPRE_PCGSet")
end end

21
src/solver_options.jl

@ -323,6 +323,27 @@ function Internals.set_options(s::GMRES, kwargs)
end end
end end
function Internals.set_options(s::ParaSails, kwargs)
solver = s.solver
for (k, v) in kwargs
if k === :Filter
@check HYPRE_ParCSRParaSailsSetFilter(solver, v)
elseif k === :Loadbal
@check HYPRE_ParCSRParaSailsSetLoadbal(solver, v)
elseif k === :Logging
@check HYPRE_ParCSRParaSailsSetLogging(solver, v)
elseif k === :Params
@check HYPRE_ParCSRParaSailsSetParams(solver, v...)
elseif k === :Reuse
@check HYPRE_ParCSRParaSailsSetReuse(solver, v)
elseif k === :Sym
@check HYPRE_ParCSRParaSailsSetSym(solver, v)
else
throw(ArgumentError("unknown option $k for HYPRE.ParaSails"))
end
end
end
function Internals.set_options(s::PCG, kwargs) function Internals.set_options(s::PCG, kwargs)
solver = s.solver solver = s.solver
for (k, v) in kwargs for (k, v) in kwargs

27
src/solvers.jl

@ -227,6 +227,33 @@ function Internals.set_precond(gmres::GMRES, p::HYPRESolver)
end end
#####################
# (ParCSR)ParaSails #
#####################
mutable struct ParaSails <: HYPRESolver
comm::MPI.Comm
solver::HYPRE_Solver
function ParaSails(comm::MPI.Comm=MPI.COMM_WORLD; kwargs...)
# Note: comm is used in this solver so default to COMM_WORLD
solver = new(comm, C_NULL)
solver_ref = Ref{HYPRE_Solver}(C_NULL)
@check HYPRE_ParCSRParaSailsCreate(comm, solver_ref)
solver.solver = solver_ref[]
# Attach a finalizer
finalizer(x -> HYPRE_ParCSRParaSailsDestroy(x.solver), solver)
# Set the options
Internals.set_options(solver, kwargs)
return solver
end
end
const ParCSRParaSails = ParaSails
Internals.setup_func(::ParaSails) = HYPRE_ParCSRParaSailsSetup
Internals.solve_func(::ParaSails) = HYPRE_ParCSRParaSailsSolve
############### ###############
# (ParCSR)PCG # # (ParCSR)PCG #
############### ###############

24
test/runtests.jl

@ -409,6 +409,30 @@ end
@test x A \ b atol=tol @test x A \ b atol=tol
end end
@testset "(ParCSR)ParaSails" begin
# Solver constructor and options
@test_throws(
ArgumentError("unknown option UnknownOption for HYPRE.ParaSails"),
HYPRE.ParaSails(; UnknownOption = 1)
)
# Setup
A = sprand(100, 100, 0.05); A = A'A + 5I
b = rand(100)
x = zeros(100)
ilower, iupper = 1, size(A, 1)
A_h = HYPREMatrix(A, ilower, iupper)
b_h = HYPREVector(b, ilower, iupper)
x_h = HYPREVector(b, ilower, iupper)
# Solve with ParaSails as preconditioner
tol = 1e-9
parasails = HYPRE.ParaSails()
pcg = HYPRE.PCG(; Tol = tol, Precond = parasails)
HYPRE.solve!(pcg, x_h, A_h, b_h)
copy!(x, x_h)
# Test result with direct solver
@test x A \ b atol=tol
end
@testset "(ParCSR)PCG" begin @testset "(ParCSR)PCG" begin
# Solver constructor and options # Solver constructor and options
@test_throws( @test_throws(

Loading…
Cancel
Save