Skip to content

Commit 7bdf88e

Browse files
committed
use LinearSolve precs setup
1 parent bdacb9c commit 7bdf88e

File tree

15 files changed

+94
-172
lines changed

15 files changed

+94
-172
lines changed

docs/src/native/solvers.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,6 @@ documentation.
1818
uses the LinearSolve.jl default algorithm choice. For more information on available
1919
algorithm choices, see the
2020
[LinearSolve.jl documentation](https://docs.sciml.ai/LinearSolve/stable/).
21-
- `precs`: the choice of preconditioners for the linear solver. Defaults to using no
22-
preconditioners. For more information on specifying preconditioners for LinearSolve
23-
algorithms, consult the
24-
[LinearSolve.jl documentation](https://docs.sciml.ai/LinearSolve/stable/).
2521
- `linesearch`: the line search algorithm to use. Defaults to [`NoLineSearch()`](@ref),
2622
which means that no line search is performed. Algorithms from
2723
[`LineSearches.jl`](https://github.com/JuliaNLSolvers/LineSearches.jl/) must be

docs/src/tutorials/large_systems.md

Lines changed: 15 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -221,35 +221,27 @@ choices, see the
221221

222222
Any [LinearSolve.jl-compatible preconditioner](https://docs.sciml.ai/LinearSolve/stable/basics/Preconditioners/)
223223
can be used as a preconditioner in the linear solver interface. To define preconditioners,
224-
one must define a `precs` function in compatible with nonlinear solvers which returns the
224+
one must define a `precs` function in compatible with linear solver which returns the
225225
left and right preconditioners, matrices which approximate the inverse of `W = I - gamma*J`
226226
used in the solution of the ODE. An example of this with using
227227
[IncompleteLU.jl](https://github.com/haampie/IncompleteLU.jl) is as follows:
228228

229229
```julia
230-
# FIXME: On 1.10+ this is broken. Skipping this for now.
231230
using IncompleteLU
232231

233-
function incompletelu(W, du, u, p, t, newW, Plprev, Prprev, solverdata)
234-
if newW === nothing || newW
235-
Pl = ilu(W, τ = 50.0)
236-
else
237-
Pl = Plprev
238-
end
232+
function incompletelu(W, p=nothing)
233+
Pl = ilu(W, τ = 50.0)
239234
Pl, nothing
240235
end
241236

242237
@btime solve(prob_brusselator_2d_sparse,
243-
NewtonRaphson(linsolve = KrylovJL_GMRES(), precs = incompletelu, concrete_jac = true));
244-
nothing # hide
238+
NewtonRaphson(linsolve = KrylovJL_GMRES(precs = incompletelu), concrete_jac = true));
239+
nothing
245240
```
246241

247242
Notice a few things about this preconditioner. This preconditioner uses the sparse Jacobian,
248243
and thus we set `concrete_jac = true` to tell the algorithm to generate the Jacobian
249-
(otherwise, a Jacobian-free algorithm is used with GMRES by default). Then `newW = true`
250-
whenever a new `W` matrix is computed, and `newW = nothing` during the startup phase of the
251-
solver. Thus, we do a check `newW === nothing || newW` and when true, it's only at these
252-
points when we update the preconditioner, otherwise we just pass on the previous version.
244+
(otherwise, a Jacobian-free algorithm is used with GMRES by default).
253245
We use `convert(AbstractMatrix,W)` to get the concrete `W` matrix (matching `jac_prototype`,
254246
thus `SpraseMatrixCSC`) which we can use in the preconditioner's definition. Then we use
255247
`IncompleteLU.ilu` on that sparse matrix to generate the preconditioner. We return
@@ -265,39 +257,31 @@ which is more automatic. The setup is very similar to before:
265257
```@example ill_conditioned_nlprob
266258
using AlgebraicMultigrid
267259
268-
function algebraicmultigrid(W, du, u, p, t, newW, Plprev, Prprev, solverdata)
269-
if newW === nothing || newW
270-
Pl = aspreconditioner(ruge_stuben(convert(AbstractMatrix, W)))
271-
else
272-
Pl = Plprev
273-
end
260+
function algebraicmultigrid(W, p=nothing)
261+
Pl = aspreconditioner(ruge_stuben(convert(AbstractMatrix, W)))
274262
Pl, nothing
275263
end
276264
277265
@btime solve(prob_brusselator_2d_sparse,
278266
NewtonRaphson(
279-
linsolve = KrylovJL_GMRES(), precs = algebraicmultigrid, concrete_jac = true));
267+
linsolve = KrylovJL_GMRES(precs = algebraicmultigrid), concrete_jac = true));
280268
nothing # hide
281269
```
282270

283271
or with a Jacobi smoother:
284272

285273
```@example ill_conditioned_nlprob
286-
function algebraicmultigrid2(W, du, u, p, t, newW, Plprev, Prprev, solverdata)
287-
if newW === nothing || newW
288-
A = convert(AbstractMatrix, W)
289-
Pl = AlgebraicMultigrid.aspreconditioner(AlgebraicMultigrid.ruge_stuben(
290-
A, presmoother = AlgebraicMultigrid.Jacobi(rand(size(A, 1))),
291-
postsmoother = AlgebraicMultigrid.Jacobi(rand(size(A, 1)))))
292-
else
293-
Pl = Plprev
294-
end
274+
function algebraicmultigrid2(W, p=nothing)
275+
A = convert(AbstractMatrix, W)
276+
Pl = AlgebraicMultigrid.aspreconditioner(AlgebraicMultigrid.ruge_stuben(
277+
A, presmoother = AlgebraicMultigrid.Jacobi(rand(size(A, 1))),
278+
postsmoother = AlgebraicMultigrid.Jacobi(rand(size(A, 1)))))
295279
Pl, nothing
296280
end
297281
298282
@btime solve(prob_brusselator_2d_sparse,
299283
NewtonRaphson(
300-
linsolve = KrylovJL_GMRES(), precs = algebraicmultigrid2, concrete_jac = true));
284+
linsolve = KrylovJL_GMRES(precs = algebraicmultigrid2), concrete_jac = true));
301285
nothing # hide
302286
```
303287

src/algorithms/gauss_newton.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
"""
22
GaussNewton(; concrete_jac = nothing, linsolve = nothing, linesearch = NoLineSearch(),
3-
precs = DEFAULT_PRECS, adkwargs...)
3+
adkwargs...)
44
55
An advanced GaussNewton implementation with support for efficient handling of sparse
66
matrices via colored automatic differentiation and preconditioned linear solvers. Designed
77
for large-scale and numerically-difficult nonlinear least squares problems.
88
"""
9-
function GaussNewton(; concrete_jac = nothing, linsolve = nothing, precs = DEFAULT_PRECS,
9+
function GaussNewton(; concrete_jac = nothing, linsolve = nothing,
1010
linesearch = NoLineSearch(), vjp_autodiff = nothing, autodiff = nothing)
11-
descent = NewtonDescent(; linsolve, precs)
11+
descent = NewtonDescent(; linsolve)
1212
return GeneralizedFirstOrderAlgorithm(; concrete_jac, name = :GaussNewton, descent,
1313
jacobian_ad = autodiff, reverse_ad = vjp_autodiff, linesearch)
1414
end

src/algorithms/klement.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""
22
Klement(; max_resets = 100, linsolve = NoLineSearch(), linesearch = nothing,
3-
precs = DEFAULT_PRECS, alpha = nothing, init_jacobian::Val = Val(:identity),
3+
alpha = nothing, init_jacobian::Val = Val(:identity),
44
autodiff = nothing)
55
66
An implementation of `Klement` [klement2014using](@citep) with line search, preconditioning
@@ -25,7 +25,7 @@ over this.
2525
differentiable problems.
2626
"""
2727
function Klement(; max_resets::Int = 100, linsolve = nothing, alpha = nothing,
28-
linesearch = NoLineSearch(), precs = DEFAULT_PRECS,
28+
linesearch = NoLineSearch(),
2929
autodiff = nothing, init_jacobian::Val{IJ} = Val(:identity)) where {IJ}
3030
if !(linesearch isa AbstractNonlinearSolveLineSearchAlgorithm)
3131
Base.depwarn(
@@ -48,7 +48,7 @@ function Klement(; max_resets::Int = 100, linsolve = nothing, alpha = nothing,
4848
CJ = IJ === :true_jacobian || IJ === :true_jacobian_diagonal
4949

5050
return ApproximateJacobianSolveAlgorithm{CJ, :Klement}(;
51-
linesearch, descent = NewtonDescent(; linsolve, precs),
51+
linesearch, descent = NewtonDescent(; linsolve),
5252
update_rule = KlementUpdateRule(),
5353
reinit_rule = IllConditionedJacobianReset(), max_resets, initialization)
5454
end

src/algorithms/levenberg_marquardt.jl

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""
22
LevenbergMarquardt(; linsolve = nothing,
3-
precs = DEFAULT_PRECS, damping_initial::Real = 1.0, α_geodesic::Real = 0.75,
3+
damping_initial::Real = 1.0, α_geodesic::Real = 0.75,
44
damping_increase_factor::Real = 2.0, damping_decrease_factor::Real = 3.0,
55
finite_diff_step_geodesic = 0.1, b_uphill::Real = 1.0, autodiff = nothing,
66
min_damping_D::Real = 1e-8, disable_geodesic = Val(false))
@@ -31,7 +31,7 @@ For the remaining arguments, see [`GeodesicAcceleration`](@ref) and
3131
[`NonlinearSolve.LevenbergMarquardtTrustRegion`](@ref) documentations.
3232
"""
3333
function LevenbergMarquardt(;
34-
concrete_jac = missing, linsolve = nothing, precs = DEFAULT_PRECS,
34+
concrete_jac = missing, linsolve = nothing,
3535
damping_initial::Real = 1.0, α_geodesic::Real = 0.75,
3636
damping_increase_factor::Real = 2.0, damping_decrease_factor::Real = 3.0,
3737
finite_diff_step_geodesic = 0.1, b_uphill::Real = 1.0,
@@ -45,7 +45,6 @@ function LevenbergMarquardt(;
4545
end
4646

4747
descent = DampedNewtonDescent(; linsolve,
48-
precs,
4948
initial_damping = damping_initial,
5049
damping_fn = LevenbergMarquardtDampingFunction(
5150
damping_increase_factor, damping_decrease_factor, min_damping_D))

src/algorithms/pseudo_transient.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""
22
PseudoTransient(; concrete_jac = nothing, linsolve = nothing,
33
linesearch::AbstractNonlinearSolveLineSearchAlgorithm = NoLineSearch(),
4-
precs = DEFAULT_PRECS, autodiff = nothing)
4+
autodiff = nothing)
55
66
An implementation of PseudoTransient Method [coffey2003pseudotransient](@cite) that is used
77
to solve steady state problems in an accelerated manner. It uses an adaptive time-stepping
@@ -17,8 +17,8 @@ This implementation specifically uses "switched evolution relaxation"
1717
"""
1818
function PseudoTransient(; concrete_jac = nothing, linsolve = nothing,
1919
linesearch::AbstractNonlinearSolveLineSearchAlgorithm = NoLineSearch(),
20-
precs = DEFAULT_PRECS, autodiff = nothing, alpha_initial = 1e-3)
21-
descent = DampedNewtonDescent(; linsolve, precs, initial_damping = alpha_initial,
20+
autodiff = nothing, alpha_initial = 1e-3)
21+
descent = DampedNewtonDescent(; linsolve, initial_damping = alpha_initial,
2222
damping_fn = SwitchedEvolutionRelaxation())
2323
return GeneralizedFirstOrderAlgorithm(;
2424
concrete_jac, name = :PseudoTransient, linesearch, descent, jacobian_ad = autodiff)

src/algorithms/raphson.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
"""
22
NewtonRaphson(; concrete_jac = nothing, linsolve = nothing, linesearch = NoLineSearch(),
3-
precs = DEFAULT_PRECS, autodiff = nothing)
3+
autodiff = nothing)
44
55
An advanced NewtonRaphson implementation with support for efficient handling of sparse
66
matrices via colored automatic differentiation and preconditioned linear solvers. Designed
77
for large-scale and numerically-difficult nonlinear systems.
88
"""
99
function NewtonRaphson(; concrete_jac = nothing, linsolve = nothing,
10-
linesearch = NoLineSearch(), precs = DEFAULT_PRECS, autodiff = nothing)
11-
descent = NewtonDescent(; linsolve, precs)
10+
linesearch = NoLineSearch(), autodiff = nothing)
11+
descent = NewtonDescent(; linsolve)
1212
return GeneralizedFirstOrderAlgorithm(;
1313
concrete_jac, name = :NewtonRaphson, linesearch, descent, jacobian_ad = autodiff)
1414
end

src/algorithms/trust_region.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"""
2-
TrustRegion(; concrete_jac = nothing, linsolve = nothing, precs = DEFAULT_PRECS,
2+
TrustRegion(; concrete_jac = nothing, linsolve = nothing,
33
radius_update_scheme = RadiusUpdateSchemes.Simple, max_trust_radius::Real = 0 // 1,
44
initial_trust_radius::Real = 0 // 1, step_threshold::Real = 1 // 10000,
55
shrink_threshold::Real = 1 // 4, expand_threshold::Real = 3 // 4,
@@ -19,13 +19,13 @@ for large-scale and numerically-difficult nonlinear systems.
1919
For the remaining arguments, see [`NonlinearSolve.GenericTrustRegionScheme`](@ref)
2020
documentation.
2121
"""
22-
function TrustRegion(; concrete_jac = nothing, linsolve = nothing, precs = DEFAULT_PRECS,
22+
function TrustRegion(; concrete_jac = nothing, linsolve = nothing,
2323
radius_update_scheme = RadiusUpdateSchemes.Simple, max_trust_radius::Real = 0 // 1,
2424
initial_trust_radius::Real = 0 // 1, step_threshold::Real = 1 // 10000,
2525
shrink_threshold::Real = 1 // 4, expand_threshold::Real = 3 // 4,
2626
shrink_factor::Real = 1 // 4, expand_factor::Real = 2 // 1,
2727
max_shrink_times::Int = 32, autodiff = nothing, vjp_autodiff = nothing)
28-
descent = Dogleg(; linsolve, precs)
28+
descent = Dogleg(; linsolve)
2929
if autodiff !== nothing && ADTypes.mode(autodiff) isa ADTypes.ForwardMode
3030
forward_ad = autodiff
3131
else

0 commit comments

Comments
 (0)