mirror of https://github.com/fredrikekre/HYPRE.jl
Browse Source
This commits contains the solver interface:
A = HYPREMatrix(...)
b = HYPREVector(...)
x = HYPREVector(...)
solver = HYPRESolver(; options...)
solve!(solver, x, A, b)
where the abstract type HYPRESolver is replaced by a concrete solver
implementation (this commit includes the concrete
implementation/wrapping of BoomerAMG <: HYPRESolver).
Solver settings are passed as keyword arguments to the solver
constructor, cf. SetXXX functions in HYPRE.
For example, to create a BoomerAMG solver, and setting the tolerance:
solver = BoomerAMG(Tol = 1e-7)
Keyword argument names correspond directly to the solvers SetXXX
function in HYPRE; passing Tol corresponds to
HYPRE_BoomerAMGSetTol(solver, 1e-7).
fe/wip
6 changed files with 361 additions and 0 deletions
@ -0,0 +1,40 @@
@@ -0,0 +1,40 @@
|
||||
using HYPRE.LibHYPRE |
||||
|
||||
function generate_options(io, structname, prefix) |
||||
println(io, "") |
||||
println(io, "function Internals.set_options(s::$(structname), kwargs)") |
||||
println(io, " solver = s.solver") |
||||
println(io, " for (k, v) in kwargs") |
||||
r = Regex("^" * prefix * "([A-Z].*)\$") |
||||
ns = sort!(filter!(x -> occursin(r, string(x)), names(LibHYPRE))) |
||||
first = true |
||||
for n in ns |
||||
m = get(methods(getfield(LibHYPRE, n)), 1, nothing) |
||||
m === nothing && continue |
||||
nargs = m.nargs - 1 |
||||
k = String(match(r, string(n))[1]) |
||||
print(io, " $(first ? "" : "else")if k === :$(k)") |
||||
println(io) |
||||
if nargs == 1 |
||||
println(io, " @check ", n, "(solver)") |
||||
elseif nargs == 2 |
||||
println(io, " @check ", n, "(solver, v)") |
||||
else # nargs >= 3 |
||||
println(io, " @check ", n, "(solver, v...)") |
||||
end |
||||
first = false |
||||
end |
||||
println(io, " end") |
||||
println(io, " end") |
||||
println(io, "end") |
||||
end |
||||
|
||||
open(joinpath(@__DIR__, "..", "src", "solver_options.jl"), "w") do io |
||||
println(io, "# SPDX-License-Identifier: MIT") |
||||
println(io, "") |
||||
println(io, "# This file is automatically generated by gen/solver_options.jl") |
||||
println(io, "") |
||||
println(io, "Internals.set_options(::HYPRESolver, kwargs) = nothing") |
||||
|
||||
generate_options(io, "BoomerAMG", "HYPRE_BoomerAMGSet") |
||||
end |
||||
@ -0,0 +1,260 @@
@@ -0,0 +1,260 @@
|
||||
# SPDX-License-Identifier: MIT |
||||
|
||||
# This file is automatically generated by gen/solver_options.jl |
||||
|
||||
Internals.set_options(::HYPRESolver, kwargs) = nothing |
||||
|
||||
function Internals.set_options(s::BoomerAMG, kwargs) |
||||
solver = s.solver |
||||
for (k, v) in kwargs |
||||
if k === :ADropTol |
||||
@check HYPRE_BoomerAMGSetADropTol(solver, v) |
||||
elseif k === :ADropType |
||||
@check HYPRE_BoomerAMGSetADropType(solver, v) |
||||
elseif k === :AddLastLvl |
||||
@check HYPRE_BoomerAMGSetAddLastLvl(solver, v) |
||||
elseif k === :AddRelaxType |
||||
@check HYPRE_BoomerAMGSetAddRelaxType(solver, v) |
||||
elseif k === :AddRelaxWt |
||||
@check HYPRE_BoomerAMGSetAddRelaxWt(solver, v) |
||||
elseif k === :Additive |
||||
@check HYPRE_BoomerAMGSetAdditive(solver, v) |
||||
elseif k === :AggInterpType |
||||
@check HYPRE_BoomerAMGSetAggInterpType(solver, v) |
||||
elseif k === :AggNumLevels |
||||
@check HYPRE_BoomerAMGSetAggNumLevels(solver, v) |
||||
elseif k === :AggP12MaxElmts |
||||
@check HYPRE_BoomerAMGSetAggP12MaxElmts(solver, v) |
||||
elseif k === :AggP12TruncFactor |
||||
@check HYPRE_BoomerAMGSetAggP12TruncFactor(solver, v) |
||||
elseif k === :AggPMaxElmts |
||||
@check HYPRE_BoomerAMGSetAggPMaxElmts(solver, v) |
||||
elseif k === :AggTruncFactor |
||||
@check HYPRE_BoomerAMGSetAggTruncFactor(solver, v) |
||||
elseif k === :CGCIts |
||||
@check HYPRE_BoomerAMGSetCGCIts(solver, v) |
||||
elseif k === :CPoints |
||||
@check HYPRE_BoomerAMGSetCPoints(solver, v...) |
||||
elseif k === :CRRate |
||||
@check HYPRE_BoomerAMGSetCRRate(solver, v) |
||||
elseif k === :CRStrongTh |
||||
@check HYPRE_BoomerAMGSetCRStrongTh(solver, v) |
||||
elseif k === :CRUseCG |
||||
@check HYPRE_BoomerAMGSetCRUseCG(solver, v) |
||||
elseif k === :ChebyEigEst |
||||
@check HYPRE_BoomerAMGSetChebyEigEst(solver, v) |
||||
elseif k === :ChebyFraction |
||||
@check HYPRE_BoomerAMGSetChebyFraction(solver, v) |
||||
elseif k === :ChebyOrder |
||||
@check HYPRE_BoomerAMGSetChebyOrder(solver, v) |
||||
elseif k === :ChebyScale |
||||
@check HYPRE_BoomerAMGSetChebyScale(solver, v) |
||||
elseif k === :ChebyVariant |
||||
@check HYPRE_BoomerAMGSetChebyVariant(solver, v) |
||||
elseif k === :CoarsenCutFactor |
||||
@check HYPRE_BoomerAMGSetCoarsenCutFactor(solver, v) |
||||
elseif k === :CoarsenType |
||||
@check HYPRE_BoomerAMGSetCoarsenType(solver, v) |
||||
elseif k === :ConvergeType |
||||
@check HYPRE_BoomerAMGSetConvergeType(solver, v) |
||||
elseif k === :CoordDim |
||||
@check HYPRE_BoomerAMGSetCoordDim(solver, v) |
||||
elseif k === :Coordinates |
||||
@check HYPRE_BoomerAMGSetCoordinates(solver, v) |
||||
elseif k === :CpointsToKeep |
||||
@check HYPRE_BoomerAMGSetCpointsToKeep(solver, v...) |
||||
elseif k === :CycleNumSweeps |
||||
@check HYPRE_BoomerAMGSetCycleNumSweeps(solver, v...) |
||||
elseif k === :CycleRelaxType |
||||
@check HYPRE_BoomerAMGSetCycleRelaxType(solver, v...) |
||||
elseif k === :CycleType |
||||
@check HYPRE_BoomerAMGSetCycleType(solver, v) |
||||
elseif k === :DebugFlag |
||||
@check HYPRE_BoomerAMGSetDebugFlag(solver, v) |
||||
elseif k === :DofFunc |
||||
@check HYPRE_BoomerAMGSetDofFunc(solver, v) |
||||
elseif k === :DomainType |
||||
@check HYPRE_BoomerAMGSetDomainType(solver, v) |
||||
elseif k === :DropTol |
||||
@check HYPRE_BoomerAMGSetDropTol(solver, v) |
||||
elseif k === :EuBJ |
||||
@check HYPRE_BoomerAMGSetEuBJ(solver, v) |
||||
elseif k === :EuLevel |
||||
@check HYPRE_BoomerAMGSetEuLevel(solver, v) |
||||
elseif k === :EuSparseA |
||||
@check HYPRE_BoomerAMGSetEuSparseA(solver, v) |
||||
elseif k === :EuclidFile |
||||
@check HYPRE_BoomerAMGSetEuclidFile(solver, v) |
||||
elseif k === :FCycle |
||||
@check HYPRE_BoomerAMGSetFCycle(solver, v) |
||||
elseif k === :FPoints |
||||
@check HYPRE_BoomerAMGSetFPoints(solver, v...) |
||||
elseif k === :Filter |
||||
@check HYPRE_BoomerAMGSetFilter(solver, v) |
||||
elseif k === :FilterThresholdR |
||||
@check HYPRE_BoomerAMGSetFilterThresholdR(solver, v) |
||||
elseif k === :GMRESSwitchR |
||||
@check HYPRE_BoomerAMGSetGMRESSwitchR(solver, v) |
||||
elseif k === :GSMG |
||||
@check HYPRE_BoomerAMGSetGSMG(solver, v) |
||||
elseif k === :GridRelaxPoints |
||||
@check HYPRE_BoomerAMGSetGridRelaxPoints(solver, v) |
||||
elseif k === :GridRelaxType |
||||
@check HYPRE_BoomerAMGSetGridRelaxType(solver, v) |
||||
elseif k === :ILUDroptol |
||||
@check HYPRE_BoomerAMGSetILUDroptol(solver, v) |
||||
elseif k === :ILULevel |
||||
@check HYPRE_BoomerAMGSetILULevel(solver, v) |
||||
elseif k === :ILUMaxIter |
||||
@check HYPRE_BoomerAMGSetILUMaxIter(solver, v) |
||||
elseif k === :ILUMaxRowNnz |
||||
@check HYPRE_BoomerAMGSetILUMaxRowNnz(solver, v) |
||||
elseif k === :ILUType |
||||
@check HYPRE_BoomerAMGSetILUType(solver, v) |
||||
elseif k === :ISType |
||||
@check HYPRE_BoomerAMGSetISType(solver, v) |
||||
elseif k === :InterpType |
||||
@check HYPRE_BoomerAMGSetInterpType(solver, v) |
||||
elseif k === :InterpVecAbsQTrunc |
||||
@check HYPRE_BoomerAMGSetInterpVecAbsQTrunc(solver, v) |
||||
elseif k === :InterpVecQMax |
||||
@check HYPRE_BoomerAMGSetInterpVecQMax(solver, v) |
||||
elseif k === :InterpVecVariant |
||||
@check HYPRE_BoomerAMGSetInterpVecVariant(solver, v) |
||||
elseif k === :InterpVectors |
||||
@check HYPRE_BoomerAMGSetInterpVectors(solver, v...) |
||||
elseif k === :IsTriangular |
||||
@check HYPRE_BoomerAMGSetIsTriangular(solver, v) |
||||
elseif k === :IsolatedFPoints |
||||
@check HYPRE_BoomerAMGSetIsolatedFPoints(solver, v...) |
||||
elseif k === :JacobiTruncThreshold |
||||
@check HYPRE_BoomerAMGSetJacobiTruncThreshold(solver, v) |
||||
elseif k === :KeepSameSign |
||||
@check HYPRE_BoomerAMGSetKeepSameSign(solver, v) |
||||
elseif k === :KeepTranspose |
||||
@check HYPRE_BoomerAMGSetKeepTranspose(solver, v) |
||||
elseif k === :Level |
||||
@check HYPRE_BoomerAMGSetLevel(solver, v) |
||||
elseif k === :LevelNonGalerkinTol |
||||
@check HYPRE_BoomerAMGSetLevelNonGalerkinTol(solver, v...) |
||||
elseif k === :LevelOuterWt |
||||
@check HYPRE_BoomerAMGSetLevelOuterWt(solver, v...) |
||||
elseif k === :LevelRelaxWt |
||||
@check HYPRE_BoomerAMGSetLevelRelaxWt(solver, v...) |
||||
elseif k === :Logging |
||||
@check HYPRE_BoomerAMGSetLogging(solver, v) |
||||
elseif k === :MaxCoarseSize |
||||
@check HYPRE_BoomerAMGSetMaxCoarseSize(solver, v) |
||||
elseif k === :MaxIter |
||||
@check HYPRE_BoomerAMGSetMaxIter(solver, v) |
||||
elseif k === :MaxLevels |
||||
@check HYPRE_BoomerAMGSetMaxLevels(solver, v) |
||||
elseif k === :MaxNzPerRow |
||||
@check HYPRE_BoomerAMGSetMaxNzPerRow(solver, v) |
||||
elseif k === :MaxRowSum |
||||
@check HYPRE_BoomerAMGSetMaxRowSum(solver, v) |
||||
elseif k === :MeasureType |
||||
@check HYPRE_BoomerAMGSetMeasureType(solver, v) |
||||
elseif k === :MinCoarseSize |
||||
@check HYPRE_BoomerAMGSetMinCoarseSize(solver, v) |
||||
elseif k === :MinIter |
||||
@check HYPRE_BoomerAMGSetMinIter(solver, v) |
||||
elseif k === :ModuleRAP2 |
||||
@check HYPRE_BoomerAMGSetModuleRAP2(solver, v) |
||||
elseif k === :MultAddPMaxElmts |
||||
@check HYPRE_BoomerAMGSetMultAddPMaxElmts(solver, v) |
||||
elseif k === :MultAddTruncFactor |
||||
@check HYPRE_BoomerAMGSetMultAddTruncFactor(solver, v) |
||||
elseif k === :MultAdditive |
||||
@check HYPRE_BoomerAMGSetMultAdditive(solver, v) |
||||
elseif k === :Nodal |
||||
@check HYPRE_BoomerAMGSetNodal(solver, v) |
||||
elseif k === :NodalDiag |
||||
@check HYPRE_BoomerAMGSetNodalDiag(solver, v) |
||||
elseif k === :NonGalerkTol |
||||
@check HYPRE_BoomerAMGSetNonGalerkTol(solver, v...) |
||||
elseif k === :NonGalerkinTol |
||||
@check HYPRE_BoomerAMGSetNonGalerkinTol(solver, v) |
||||
elseif k === :NumCRRelaxSteps |
||||
@check HYPRE_BoomerAMGSetNumCRRelaxSteps(solver, v) |
||||
elseif k === :NumFunctions |
||||
@check HYPRE_BoomerAMGSetNumFunctions(solver, v) |
||||
elseif k === :NumGridSweeps |
||||
@check HYPRE_BoomerAMGSetNumGridSweeps(solver, v) |
||||
elseif k === :NumPaths |
||||
@check HYPRE_BoomerAMGSetNumPaths(solver, v) |
||||
elseif k === :NumSamples |
||||
@check HYPRE_BoomerAMGSetNumSamples(solver, v) |
||||
elseif k === :NumSweeps |
||||
@check HYPRE_BoomerAMGSetNumSweeps(solver, v) |
||||
elseif k === :OldDefault |
||||
@check HYPRE_BoomerAMGSetOldDefault(solver) |
||||
elseif k === :Omega |
||||
@check HYPRE_BoomerAMGSetOmega(solver, v) |
||||
elseif k === :OuterWt |
||||
@check HYPRE_BoomerAMGSetOuterWt(solver, v) |
||||
elseif k === :Overlap |
||||
@check HYPRE_BoomerAMGSetOverlap(solver, v) |
||||
elseif k === :PMaxElmts |
||||
@check HYPRE_BoomerAMGSetPMaxElmts(solver, v) |
||||
elseif k === :PlotFileName |
||||
@check HYPRE_BoomerAMGSetPlotFileName(solver, v) |
||||
elseif k === :PlotGrids |
||||
@check HYPRE_BoomerAMGSetPlotGrids(solver, v) |
||||
elseif k === :PostInterpType |
||||
@check HYPRE_BoomerAMGSetPostInterpType(solver, v) |
||||
elseif k === :PrintFileName |
||||
@check HYPRE_BoomerAMGSetPrintFileName(solver, v) |
||||
elseif k === :PrintLevel |
||||
@check HYPRE_BoomerAMGSetPrintLevel(solver, v) |
||||
elseif k === :RAP2 |
||||
@check HYPRE_BoomerAMGSetRAP2(solver, v) |
||||
elseif k === :Redundant |
||||
@check HYPRE_BoomerAMGSetRedundant(solver, v) |
||||
elseif k === :RelaxOrder |
||||
@check HYPRE_BoomerAMGSetRelaxOrder(solver, v) |
||||
elseif k === :RelaxType |
||||
@check HYPRE_BoomerAMGSetRelaxType(solver, v) |
||||
elseif k === :RelaxWeight |
||||
@check HYPRE_BoomerAMGSetRelaxWeight(solver, v) |
||||
elseif k === :RelaxWt |
||||
@check HYPRE_BoomerAMGSetRelaxWt(solver, v) |
||||
elseif k === :Restriction |
||||
@check HYPRE_BoomerAMGSetRestriction(solver, v) |
||||
elseif k === :SCommPkgSwitch |
||||
@check HYPRE_BoomerAMGSetSCommPkgSwitch(solver, v) |
||||
elseif k === :Sabs |
||||
@check HYPRE_BoomerAMGSetSabs(solver, v) |
||||
elseif k === :SchwarzRlxWeight |
||||
@check HYPRE_BoomerAMGSetSchwarzRlxWeight(solver, v) |
||||
elseif k === :SchwarzUseNonSymm |
||||
@check HYPRE_BoomerAMGSetSchwarzUseNonSymm(solver, v) |
||||
elseif k === :SepWeight |
||||
@check HYPRE_BoomerAMGSetSepWeight(solver, v) |
||||
elseif k === :SeqThreshold |
||||
@check HYPRE_BoomerAMGSetSeqThreshold(solver, v) |
||||
elseif k === :Simple |
||||
@check HYPRE_BoomerAMGSetSimple(solver, v) |
||||
elseif k === :SmoothNumLevels |
||||
@check HYPRE_BoomerAMGSetSmoothNumLevels(solver, v) |
||||
elseif k === :SmoothNumSweeps |
||||
@check HYPRE_BoomerAMGSetSmoothNumSweeps(solver, v) |
||||
elseif k === :SmoothType |
||||
@check HYPRE_BoomerAMGSetSmoothType(solver, v) |
||||
elseif k === :StrongThreshold |
||||
@check HYPRE_BoomerAMGSetStrongThreshold(solver, v) |
||||
elseif k === :StrongThresholdR |
||||
@check HYPRE_BoomerAMGSetStrongThresholdR(solver, v) |
||||
elseif k === :Sym |
||||
@check HYPRE_BoomerAMGSetSym(solver, v) |
||||
elseif k === :Threshold |
||||
@check HYPRE_BoomerAMGSetThreshold(solver, v) |
||||
elseif k === :Tol |
||||
@check HYPRE_BoomerAMGSetTol(solver, v) |
||||
elseif k === :TruncFactor |
||||
@check HYPRE_BoomerAMGSetTruncFactor(solver, v) |
||||
elseif k === :Variant |
||||
@check HYPRE_BoomerAMGSetVariant(solver, v) |
||||
end |
||||
end |
||||
end |
||||
@ -0,0 +1,36 @@
@@ -0,0 +1,36 @@
|
||||
# SPDX-License-Identifier: MIT |
||||
|
||||
""" |
||||
HYPRESolver |
||||
|
||||
Abstract super type of all the wrapped HYPRE solvers. |
||||
""" |
||||
abstract type HYPRESolver end |
||||
|
||||
############# |
||||
# BoomerAMG # |
||||
############# |
||||
|
||||
mutable struct BoomerAMG <: HYPRESolver |
||||
solver::HYPRE_Solver |
||||
function BoomerAMG(; kwargs...) |
||||
solver = new(C_NULL) |
||||
solver_ref = Ref{HYPRE_Solver}(C_NULL) |
||||
@check HYPRE_BoomerAMGCreate(solver_ref) |
||||
solver.solver = solver_ref[] |
||||
# Attach a finalizer |
||||
finalizer(x -> HYPRE_BoomerAMGDestroy(x.solver), solver) |
||||
# Set the options |
||||
Internals.set_options(solver, kwargs) |
||||
return solver |
||||
end |
||||
end |
||||
|
||||
function solve!(amg::BoomerAMG, x::HYPREVector, A::HYPREMatrix, b::HYPREVector) |
||||
@check HYPRE_BoomerAMGSetup(amg.solver, A.ParCSRMatrix, b.ParVector, x.ParVector) |
||||
@check HYPRE_BoomerAMGSolve(amg.solver, A.ParCSRMatrix, b.ParVector, x.ParVector) |
||||
return x |
||||
end |
||||
|
||||
Internals.solve_func(::BoomerAMG) = HYPRE_BoomerAMGSolve |
||||
Internals.setup_func(::BoomerAMG) = HYPRE_BoomerAMGSetup |
||||
Loading…
Reference in new issue