100100
101101u0 = init_brusselator_2d(xyd_brusselator)
102102prob_brusselator_2d = NonlinearProblem(
103- brusselator_2d_loop, u0, p; abstol = 1e-10, reltol = 1e-10)
103+ brusselator_2d_loop, u0, p; abstol = 1e-10, reltol = 1e-10
104+ )
104105```
105106
106107## Choosing Jacobian Types
@@ -140,7 +141,8 @@ using SparseConnectivityTracer
140141
141142prob_brusselator_2d_autosparse = NonlinearProblem(
142143 NonlinearFunction(brusselator_2d_loop; sparsity = TracerSparsityDetector()),
143- u0, p; abstol = 1e-10, reltol = 1e-10)
144+ u0, p; abstol = 1e-10, reltol = 1e-10
145+ )
144146
145147@btime solve(prob_brusselator_2d_autosparse,
146148 NewtonRaphson(; autodiff = AutoForwardDiff(; chunksize = 12)));
@@ -235,7 +237,7 @@ choices, see the
235237
236238Any [ LinearSolve.jl-compatible preconditioner] ( https://docs.sciml.ai/LinearSolve/stable/basics/Preconditioners/ )
237239can be used as a preconditioner in the linear solver interface. To define preconditioners,
238- one must define a ` precs ` function in compatible with nonlinear solvers which returns the
240+ one must define a ` precs ` function in compatible with linear solvers which returns the
239241left and right preconditioners, matrices which approximate the inverse of ` W = I - gamma*J `
240242used in the solution of the ODE. An example of this with using
241243[ IncompleteLU.jl] ( https://github.com/haampie/IncompleteLU.jl ) is as follows:
@@ -244,26 +246,18 @@ used in the solution of the ODE. An example of this with using
244246# FIXME : On 1.10+ this is broken. Skipping this for now.
245247using IncompleteLU
246248
247- function incompletelu (W, du, u, p, t, newW, Plprev, Prprev, solverdata)
248- if newW === nothing || newW
249- Pl = ilu (W, τ = 50.0 )
250- else
251- Pl = Plprev
252- end
253- Pl, nothing
254- end
249+ incompletelu (W, p = nothing ) = ilu (W, τ = 50.0 ), LinearAlgebra. I
255250
256251@btime solve (prob_brusselator_2d_sparse,
257- NewtonRaphson (linsolve = KrylovJL_GMRES (), precs = incompletelu, concrete_jac = true ));
252+ NewtonRaphson (linsolve = KrylovJL_GMRES (precs = incompletelu), concrete_jac = true )
253+ );
258254nothing # hide
259255```
260256
261257Notice a few things about this preconditioner. This preconditioner uses the sparse Jacobian,
262258and thus we set ` concrete_jac = true ` to tell the algorithm to generate the Jacobian
263- (otherwise, a Jacobian-free algorithm is used with GMRES by default). Then ` newW = true `
264- whenever a new ` W ` matrix is computed, and ` newW = nothing ` during the startup phase of the
265- solver. Thus, we do a check ` newW === nothing || newW ` and when true, it's only at these
266- points when we update the preconditioner, otherwise we just pass on the previous version.
259+ (otherwise, a Jacobian-free algorithm is used with GMRES by default).
260+
267261We use ` convert(AbstractMatrix,W) ` to get the concrete ` W ` matrix (matching ` jac_prototype ` ,
268262thus ` SpraseMatrixCSC ` ) which we can use in the preconditioner's definition. Then we use
269263` IncompleteLU.ilu ` on that sparse matrix to generate the preconditioner. We return
@@ -279,39 +273,36 @@ which is more automatic. The setup is very similar to before:
279273``` @example ill_conditioned_nlprob
280274using AlgebraicMultigrid
281275
282- function algebraicmultigrid(W, du, u, p, t, newW, Plprev, Prprev, solverdata)
283- if newW === nothing || newW
284- Pl = aspreconditioner(ruge_stuben(convert(AbstractMatrix, W)))
285- else
286- Pl = Plprev
287- end
288- Pl, nothing
276+ function algebraicmultigrid(W, p = nothing)
277+ return aspreconditioner(ruge_stuben(convert(AbstractMatrix, W))), LinearAlgebra.I
289278end
290279
291280@btime solve(prob_brusselator_2d_sparse,
292- NewtonRaphson(linsolve = KrylovJL_GMRES(), precs = algebraicmultigrid,
293- concrete_jac = true));
281+ NewtonRaphson(
282+ linsolve = KrylovJL_GMRES(; precs = algebraicmultigrid), concrete_jac = true
283+ )
284+ );
294285nothing # hide
295286```
296287
297288or with a Jacobi smoother:
298289
299290``` @example ill_conditioned_nlprob
300- function algebraicmultigrid2(W, du, u, p, t, newW, Plprev, Prprev, solverdata)
301- if newW === nothing || newW
302- A = convert(AbstractMatrix, W)
303- Pl = AlgebraicMultigrid.aspreconditioner(AlgebraicMultigrid.ruge_stuben(
304- A, presmoother = AlgebraicMultigrid.Jacobi(rand(size(A, 1))),
305- postsmoother = AlgebraicMultigrid.Jacobi(rand(size(A, 1)))))
306- else
307- Pl = Plprev
308- end
309- Pl, nothing
291+ function algebraicmultigrid2(W, p = nothing)
292+ A = convert(AbstractMatrix, W)
293+ Pl = AlgebraicMultigrid.aspreconditioner(AlgebraicMultigrid.ruge_stuben(
294+ A, presmoother = AlgebraicMultigrid.Jacobi(rand(size(A, 1))),
295+ postsmoother = AlgebraicMultigrid.Jacobi(rand(size(A, 1)))
296+ ))
297+ return Pl, LinearAlgebra.I
310298end
311299
312- @btime solve(prob_brusselator_2d_sparse,
313- NewtonRaphson(linsolve = KrylovJL_GMRES(), precs = algebraicmultigrid2,
314- concrete_jac = true));
300+ @btime solve(
301+ prob_brusselator_2d_sparse,
302+ NewtonRaphson(
303+ linsolve = KrylovJL_GMRES(precs = algebraicmultigrid2), concrete_jac = true
304+ )
305+ );
315306nothing # hide
316307```
317308
0 commit comments