100
100
101
101
u0 = init_brusselator_2d(xyd_brusselator)
102
102
prob_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
+ )
104
105
```
105
106
106
107
## Choosing Jacobian Types
@@ -140,7 +141,8 @@ using SparseConnectivityTracer
140
141
141
142
prob_brusselator_2d_autosparse = NonlinearProblem(
142
143
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
+ )
144
146
145
147
@btime solve(prob_brusselator_2d_autosparse,
146
148
NewtonRaphson(; autodiff = AutoForwardDiff(; chunksize = 12)));
@@ -235,7 +237,7 @@ choices, see the
235
237
236
238
Any [ LinearSolve.jl-compatible preconditioner] ( https://docs.sciml.ai/LinearSolve/stable/basics/Preconditioners/ )
237
239
can 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
239
241
left and right preconditioners, matrices which approximate the inverse of ` W = I - gamma*J `
240
242
used in the solution of the ODE. An example of this with using
241
243
[ 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
244
246
# FIXME : On 1.10+ this is broken. Skipping this for now.
245
247
using IncompleteLU
246
248
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
255
250
256
251
@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
+ );
258
254
nothing # hide
259
255
```
260
256
261
257
Notice a few things about this preconditioner. This preconditioner uses the sparse Jacobian,
262
258
and 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
+
267
261
We use ` convert(AbstractMatrix,W) ` to get the concrete ` W ` matrix (matching ` jac_prototype ` ,
268
262
thus ` SpraseMatrixCSC ` ) which we can use in the preconditioner's definition. Then we use
269
263
` 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:
279
273
``` @example ill_conditioned_nlprob
280
274
using AlgebraicMultigrid
281
275
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
289
278
end
290
279
291
280
@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
+ );
294
285
nothing # hide
295
286
```
296
287
297
288
or with a Jacobi smoother:
298
289
299
290
``` @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
310
298
end
311
299
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
+ );
315
306
nothing # hide
316
307
```
317
308
0 commit comments