Skip to content

Commit

Permalink
Added AbstractTrees interface for krylov solvers
Browse files Browse the repository at this point in the history
  • Loading branch information
JordiManyer committed Oct 3, 2023
1 parent b1c50e8 commit 1cd2e36
Show file tree
Hide file tree
Showing 10 changed files with 43 additions and 23 deletions.
2 changes: 2 additions & 0 deletions src/LinearSolvers/Krylov/CGSolvers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ function CGSolver(Pl;maxiter=1000,atol=1e-12,rtol=1.e-6,flexible=false,verbose=0
return CGSolver(Pl,log,flexible)
end

AbstractTrees.children(s::CGSolver) = [s.Pl]

struct CGSymbolicSetup <: Gridap.Algebra.SymbolicSetup
solver
end
Expand Down
8 changes: 5 additions & 3 deletions src/LinearSolvers/Krylov/FGMRESSolvers.jl
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@

# FGMRES Solver
struct FGMRESSolver <: Gridap.Algebra.LinearSolver
m :: Int
Pr :: Gridap.Algebra.LinearSolver
Pl :: Union{Gridap.Algebra.LinearSolver,Nothing}
m :: Int
Pr :: Gridap.Algebra.LinearSolver
Pl :: Union{Gridap.Algebra.LinearSolver,Nothing}
outer_log :: ConvergenceLog{Float64}
inner_log :: ConvergenceLog{Float64}
end
Expand All @@ -16,6 +16,8 @@ function FGMRESSolver(m,Pr;Pl=nothing,maxiter=100,atol=1e-12,rtol=1.e-6,verbose=
return FGMRESSolver(m,Pr,Pl,outer_log,inner_log)
end

AbstractTrees.children(s::FGMRESSolver) = [s.Pr,s.Pl]

struct FGMRESSymbolicSetup <: Gridap.Algebra.SymbolicSetup
solver
end
Expand Down
2 changes: 2 additions & 0 deletions src/LinearSolvers/Krylov/GMRESSolvers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ function GMRESSolver(m;Pr=nothing,Pl=nothing,maxiter=100,atol=1e-12,rtol=1.e-6,v
return GMRESSolver(m,Pr,Pl,outer_log,inner_log)
end

AbstractTrees.children(s::GMRESSolver) = [s.Pr,s.Pl]

struct GMRESSymbolicSetup <: Gridap.Algebra.SymbolicSetup
solver
end
Expand Down
2 changes: 2 additions & 0 deletions src/LinearSolvers/Krylov/MINRESSolvers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ function MINRESSolver(;Pr=nothing,Pl=nothing,maxiter=1000,atol=1e-12,rtol=1.e-6,
return MINRESSolver(Pr,Pl,log)
end

AbstractTrees.children(s::MINRESSolver) = [s.Pr,s.Pl]

struct MINRESSymbolicSetup <: Gridap.Algebra.SymbolicSetup
solver
end
Expand Down
1 change: 1 addition & 0 deletions src/LinearSolvers/LinearSolvers.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
module LinearSolvers

using Printf
using AbstractTrees
using LinearAlgebra
using SparseArrays
using SparseMatricesCSR
Expand Down
9 changes: 0 additions & 9 deletions src/SolverInterfaces/GridapExtras.jl
Original file line number Diff line number Diff line change
@@ -1,12 +1,3 @@
# Solver Hierarchies

AbstractTrees.children(s::Gridap.Algebra.LinearSolver) = []
AbstractTrees.nodevalue(s::Gridap.Algebra.LinearSolver) = get_solver_info(s)


#function Base.show(io::IO,a::Gridap.Algebra.LinearSolver)
# AbstractTrees.print_tree(io,a)
#end

# LinearSolvers that depend on the non-linear solution

Expand Down
24 changes: 20 additions & 4 deletions src/SolverInterfaces/SolverInfos.jl
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@

struct SolverInfo{T<:Real}
struct SolverInfo
name :: String
data :: Dict{Symbol, Any}
end

SolverInfo(name::String) = SolverInfo(name,Dict{Symbol, Any}())

function get_solver_info(::Gridap.Algebra.LinearSolver)
return SolverInfo("Empty solver info")
function get_solver_info(solver::Gridap.Algebra.LinearSolver)
return SolverInfo(string(typeof(solver)))
end

function merge_info!(a::SolverInfo,b::SolverInfo;prefix="")
for (key,val) in b.data
a.data[Symbol(prefix,key)] = val
end
return a
end

function add_info!(a::SolverInfo,key::Union{Symbol,String},val;prefix="")
Expand All @@ -18,7 +25,7 @@ end
function add_convergence_info!(a::SolverInfo,log::ConvergenceLog;prefix="")
prefix = string(prefix,log.name)
add_info!(a,:num_iters,log.num_iters,prefix=prefix)
add_info!(a,:residuals,log.residuals,prefix=prefix)
add_info!(a,:residuals,copy(log.residuals),prefix=prefix)
end

function add_tolerance_info!(a::SolverInfo,tols::SolverTolerances;prefix="")
Expand All @@ -31,3 +38,12 @@ function add_tolerance_info!(a::SolverInfo,log::ConvergenceLog;prefix="")
prefix = string(prefix,log.name)
add_tolerance_info!(a,log.tols,prefix=prefix)
end

Base.summary(info::SolverInfo) = info.name

AbstractTrees.children(s::Gridap.Algebra.LinearSolver) = []
AbstractTrees.nodevalue(s::Gridap.Algebra.LinearSolver) = summary(get_solver_info(s))

function Base.show(io::IO,a::Gridap.Algebra.LinearSolver)
AbstractTrees.print_tree(io,a)
end
5 changes: 3 additions & 2 deletions src/SolverInterfaces/SolverInterfaces.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ include("SolverTolerances.jl")
include("ConvergenceLogs.jl")
include("SolverInfos.jl")

export SolverVerboseLevel, SolverConvergenceFlag
export SolverTolerances, get_solver_tolerances, set_solver_tolerances!
export ConvergenceLog, init!, update!, finalize!, reset!

export SolverInfo, SolverTolerances
export SolverVerboseLevel, SolverConvergenceFlag
export SolverInfo

end
4 changes: 4 additions & 0 deletions src/SolverInterfaces/SolverTolerances.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ end

get_solver_tolerances(s::Gridap.Algebra.LinearSolver) = @abstractmethod

function set_solver_tolerances!(s::Gridap.Algebra.LinearSolver;kwargs...)
set_solver_tolerances!(get_solver_tolerances(s);kwargs...)
end

function set_solver_tolerances!(a::SolverTolerances{T};
maxiter = 1000,
atol = eps(T),
Expand Down
9 changes: 4 additions & 5 deletions test/seq/SolverInterfacesTests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,11 @@ op = AffineFEOperator(a,l,Uh,Vh)
A, b = get_matrix(op), get_vector(op);
P = JacobiLinearSolver()

solver = LinearSolvers.CGSolver(P;rtol=1.e-8,verbose=true)
ns = numerical_setup(symbolic_setup(solver,A),A)
x = LinearSolvers.allocate_col_vector(A)
solve!(x,ns,b)

solver = LinearSolvers.GMRESSolver(10;Pl=P,rtol=1.e-8,verbose=2)
ns = numerical_setup(symbolic_setup(solver,A),A)
x = LinearSolvers.allocate_col_vector(A)
solve!(x,ns,b)



using AbstractTrees

0 comments on commit 1cd2e36

Please sign in to comment.