Skip to content

Commit d47b131

Browse files
Merge pull request #344 from ErikQQY/qqy/siam_fixedpoint
Add SIAMFANLEquations fixed point solvers
2 parents e722fad + a72da25 commit d47b131

File tree

5 files changed

+35
-11
lines changed

5 files changed

+35
-11
lines changed

Project.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ NonlinearProblemLibrary = "0.1.2"
8383
OrdinaryDiffEq = "6.63"
8484
Pkg = "1"
8585
PrecompileTools = "1.2"
86-
Printf = "1.9"
86+
Printf = "1.10"
8787
Random = "1.91"
8888
RecursiveArrayTools = "3.2"
8989
Reexport = "1.2"
@@ -92,7 +92,7 @@ SafeTestsets = "0.1"
9292
SciMLBase = "2.11"
9393
SciMLOperators = "0.3.7"
9494
SimpleNonlinearSolve = "1.0.2"
95-
SparseArrays = "1.9"
95+
SparseArrays = "1.10"
9696
SparseDiffTools = "2.14"
9797
SpeedMapping = "0.3"
9898
StableRNGs = "1"

docs/src/solvers/FixedPointSolvers.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,7 @@ In our tests, we have found the anderson method implemented here to NOT be the m
4747
robust.
4848

4949
- `NLsolveJL(; method = :anderson)`: Anderson acceleration for fixed point problems.
50+
51+
### SIAMFANLEquations.jl
52+
53+
- `SIAMFANLEquationsJL(; method = :anderson)`: Anderson acceleration for fixed point problems.

ext/NonlinearSolveSIAMFANLEquationsExt.jl

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ end
2424
# pseudo transient continuation has a fixed cost per iteration, iteration statistics are
2525
# not interesting here.
2626
@inline function __siam_fanl_equations_stats_mapping(method, sol)
27-
method === :pseudotransient && return nothing
27+
((method === :pseudotransient) || (method === :anderson)) && return nothing
2828
return SciMLBase.NLStats(sum(sol.stats.ifun), sum(sol.stats.ijac), 0, 0,
2929
sum(sol.stats.iarm))
3030
end
@@ -36,16 +36,14 @@ function SciMLBase.__solve(prob::NonlinearProblem, alg::SIAMFANLEquationsJL, arg
3636
@assert (termination_condition ===
3737
nothing)||(termination_condition isa AbsNormTerminationMode) "SIAMFANLEquationsJL does not support termination conditions!"
3838

39-
(; method, delta, linsolve) = alg
40-
41-
iip = SciMLBase.isinplace(prob)
39+
(; method, delta, linsolve, m, beta) = alg
4240

4341
T = eltype(prob.u0)
4442
atol = NonlinearSolve.DEFAULT_TOLERANCE(abstol, T)
4543
rtol = NonlinearSolve.DEFAULT_TOLERANCE(reltol, T)
4644

4745
if prob.u0 isa Number
48-
f = (u) -> prob.f(u, prob.p)
46+
f = method == :anderson ? (du, u) -> (du = prob.f(u, prob.p)) : ((u) -> prob.f(u, prob.p))
4947

5048
if method == :newton
5149
sol = nsolsc(f, prob.u0; maxit = maxiters, atol, rtol, printerr = ShT)
@@ -54,11 +52,16 @@ function SciMLBase.__solve(prob::NonlinearProblem, alg::SIAMFANLEquationsJL, arg
5452
printerr = ShT)
5553
elseif method == :secant
5654
sol = secant(f, prob.u0; maxit = maxiters, atol, rtol, printerr = ShT)
55+
elseif method == :anderson
56+
f, u = NonlinearSolve.__construct_f(prob; alias_u0,
57+
make_fixed_point = Val(true), can_handle_arbitrary_dims = Val(true))
58+
sol = aasol(f, [prob.u0], m, __zeros_like(u, 1, 2*m+4); maxit = maxiters,
59+
atol, rtol, beta = beta)
5760
end
5861

5962
retcode = __siam_fanl_equations_retcode_mapping(sol)
6063
stats = __siam_fanl_equations_stats_mapping(method, sol)
61-
resid = NonlinearSolve.evaluate_f(prob, sol.solution)
64+
resid = NonlinearSolve.evaluate_f(prob, sol.solution[1])
6265
return SciMLBase.build_solution(prob, alg, sol.solution, resid; retcode,
6366
stats, original = sol)
6467
end
@@ -104,6 +107,11 @@ function SciMLBase.__solve(prob::NonlinearProblem, alg::SIAMFANLEquationsJL, arg
104107
elseif method == :pseudotransient
105108
sol = ptcsol(f!, u, FS, FPS; atol, rtol, maxit = maxiters,
106109
delta0 = delta, printerr = ShT)
110+
elseif method == :anderson
111+
f!, u = NonlinearSolve.__construct_f(prob; alias_u0,
112+
can_handle_arbitrary_dims = Val(true), make_fixed_point = Val(true))
113+
sol = aasol(f!, u, m, zeros(T, N, 2*m+4), atol = atol, rtol = rtol,
114+
maxit = maxiters, beta = beta)
107115
end
108116
else
109117
AJ!(J, u, x) = prob.f.jac(J, x, prob.p)

src/extension_algs.jl

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -377,23 +377,30 @@ end
377377
- `method`: the choice of method for solving the nonlinear system.
378378
- `delta`: initial pseudo time step, default is 1e-3.
379379
- `linsolve` : JFNK linear solvers, choices are `gmres` and `bicgstab`.
380+
- `m`: Depth for Anderson acceleration, default as 0 for Picard iteration.
381+
- `beta`: Anderson mixing parameter, change f(x) to (1-beta)x+beta*f(x),
382+
equivalent to accelerating damped Picard iteration.
380383
381384
### Submethod Choice
382385
383386
- `:newton`: Classical Newton method.
384387
- `:pseudotransient`: Pseudo transient method.
385388
- `:secant`: Secant method for scalar equations.
389+
- `:anderson`: Anderson acceleration for fixed point iterations.
386390
"""
387391
@concrete struct SIAMFANLEquationsJL{L <: Union{Symbol, Nothing}} <:
388392
AbstractNonlinearSolveAlgorithm
389393
method::Symbol
390394
delta
391395
linsolve::L
396+
m::Int
397+
beta
392398
end
393399

394-
function SIAMFANLEquationsJL(; method = :newton, delta = 1e-3, linsolve = nothing)
400+
function SIAMFANLEquationsJL(; method = :newton, delta = 1e-3, linsolve = nothing, m = 0,
401+
beta = 1.0)
395402
if Base.get_extension(@__MODULE__, :NonlinearSolveSIAMFANLEquationsExt) === nothing
396403
error("SIAMFANLEquationsJL requires SIAMFANLEquations.jl to be loaded")
397404
end
398-
return SIAMFANLEquationsJL(method, delta, linsolve)
405+
return SIAMFANLEquationsJL(method, delta, linsolve, m, beta)
399406
end

test/wrappers/fixedpoint.jl

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using NonlinearSolve, FixedPointAcceleration, SpeedMapping, NLsolve, LinearAlgebra, Test
1+
using NonlinearSolve, FixedPointAcceleration, SpeedMapping, NLsolve, SIAMFANLEquations, LinearAlgebra, Test
22

33
# Simple Scalar Problem
44
@testset "Simple Scalar Problem" begin
@@ -14,6 +14,7 @@ using NonlinearSolve, FixedPointAcceleration, SpeedMapping, NLsolve, LinearAlgeb
1414
@test abs(solve(prob, SpeedMappingJL(; stabilize = true)).resid) 1e-10
1515

1616
@test abs(solve(prob, NLsolveJL(; method = :anderson)).resid) 1e-10
17+
@test abs(solve(prob, SIAMFANLEquationsJL(; method = :anderson)).resid) 1e-10
1718
end
1819

1920
# Simple Vector Problem
@@ -28,6 +29,7 @@ end
2829
@test maximum(abs.(solve(prob, SpeedMappingJL()).resid)) 1e-10
2930
@test maximum(abs.(solve(prob, SpeedMappingJL(; orders = [3, 2])).resid)) 1e-10
3031
@test maximum(abs.(solve(prob, SpeedMappingJL(; stabilize = true)).resid)) 1e-10
32+
@test maximum(abs.(solve(prob, SIAMFANLEquationsJL(; method = :anderson)).resid)) 1e-10
3133

3234
@test_broken maximum(abs.(solve(prob, NLsolveJL(; method = :anderson)).resid)) 1e-10
3335
end
@@ -67,6 +69,9 @@ end
6769
sol = solve(prob, NLsolveJL(; method = :anderson))
6870
@test_broken sol.u' * A[:, 3] 32.916472867168096
6971

72+
sol = solve(prob, SIAMFANLEquationsJL(; method = :anderson))
73+
@test sol.u' * A[:, 3] 32.916472867168096
74+
7075
# Non vector inputs
7176
function power_method_nonvec!(du, u, A)
7277
mul!(vec(du), A, vec(u))

0 commit comments

Comments
 (0)