22
33This tutorial is for getting into the extra features of using NonlinearSolve.jl. Solving
44ill-conditioned nonlinear systems requires specializing the linear solver on properties of
5- the Jacobian in order to cut down on the `` \mathcal{O}(n^3) ` ` linear solve and the
6- `` \mathcal{O}(n^2) ` ` back-solves. This tutorial is designed to explain the advanced usage of
5+ the Jacobian in order to cut down on the ` \mathcal{O}(n^3) ` linear solve and the
6+ ` \mathcal{O}(n^2) ` back-solves. This tutorial is designed to explain the advanced usage of
77NonlinearSolve.jl by solving the steady state stiff Brusselator partial differential
88equation (BRUSS) using NonlinearSolve.jl.
99
1010## Definition of the Brusselator Equation
1111
1212!!! note
13-
13+
1414 Feel free to skip this section: it simply defines the example problem.
1515
1616The Brusselator PDE is defined as follows:
@@ -123,38 +123,38 @@ However, if you know the sparsity of your problem, then you can pass a different
123123type. For example, a ` SparseMatrixCSC ` will give a sparse matrix. Other sparse matrix types
124124include:
125125
126- - Bidiagonal
127- - Tridiagonal
128- - SymTridiagonal
129- - BandedMatrix ([ BandedMatrices.jl] ( https://github.com/JuliaLinearAlgebra/BandedMatrices.jl ) )
130- - BlockBandedMatrix ([ BlockBandedMatrices.jl] ( https://github.com/JuliaLinearAlgebra/BlockBandedMatrices.jl ) )
126+ - Bidiagonal
127+ - Tridiagonal
128+ - SymTridiagonal
129+ - BandedMatrix ([ BandedMatrices.jl] ( https://github.com/JuliaLinearAlgebra/BandedMatrices.jl ) )
130+ - BlockBandedMatrix ([ BlockBandedMatrices.jl] ( https://github.com/JuliaLinearAlgebra/BlockBandedMatrices.jl ) )
131131
132132## Approximate Sparsity Detection & Sparse Jacobians
133133
134134In the next section, we will show how to specify ` sparsity ` to trigger automatic sparsity
135135detection.
136136
137137``` @example ill_conditioned_nlprob
138- import BenchmarkTools # for @btime
138+ import BenchmarkTools: @btime # for @btime
139139
140- BenchmarkTools.BenchmarkTools. @btime NLS.solve(prob_brusselator_2d, NLS.NewtonRaphson());
140+ @btime NLS.solve(prob_brusselator_2d, NLS.NewtonRaphson());
141141nothing # hide
142142```
143143
144144``` @example ill_conditioned_nlprob
145- import SparseConnectivityTracer
145+ import SparseConnectivityTracer, SparseMatrixColorings
146146
147147prob_brusselator_2d_autosparse = NLS.NonlinearProblem(
148148 NLS.NonlinearFunction(brusselator_2d_loop; sparsity = SparseConnectivityTracer.TracerSparsityDetector()),
149149 u0, p; abstol = 1e-10, reltol = 1e-10
150150)
151151
152- BenchmarkTools. @btime NLS.solve(prob_brusselator_2d_autosparse,
152+ @btime NLS.solve(prob_brusselator_2d_autosparse,
153153 NLS.NewtonRaphson(; autodiff = ADTypes.AutoForwardDiff(; chunksize = 12)));
154- BenchmarkTools. @btime NLS.solve(prob_brusselator_2d_autosparse,
154+ @btime NLS.solve(prob_brusselator_2d_autosparse,
155155 NLS.NewtonRaphson(; autodiff = ADTypes.AutoForwardDiff(; chunksize = 12),
156156 linsolve = LS.KLUFactorization()));
157- BenchmarkTools. @btime NLS.solve(prob_brusselator_2d_autosparse,
157+ @btime NLS.solve(prob_brusselator_2d_autosparse,
158158 NLS.NewtonRaphson(; autodiff = ADTypes.AutoForwardDiff(; chunksize = 12),
159159 linsolve = LS.KrylovJL_GMRES()));
160160nothing # hide
@@ -176,7 +176,7 @@ arguments, and it will kick out a sparse matrix with our pattern, that we can tu
176176` jac_prototype ` .
177177
178178!!! tip
179-
179+
180180 External packages like `SparseConnectivityTracer.jl` and `Symbolics.jl` provide the
181181 actual implementation of sparsity detection.
182182
@@ -205,9 +205,9 @@ prob_brusselator_2d_sparse = NLS.NonlinearProblem(ff, u0, p; abstol = 1e-10, rel
205205Now let's see how the version with sparsity compares to the version without:
206206
207207``` @example ill_conditioned_nlprob
208- BenchmarkTools. @btime NLS.solve(prob_brusselator_2d, NLS.NewtonRaphson());
209- BenchmarkTools. @btime NLS.solve(prob_brusselator_2d_sparse, NLS.NewtonRaphson());
210- BenchmarkTools. @btime NLS.solve(prob_brusselator_2d_sparse, NLS.NewtonRaphson(linsolve = LS.KLUFactorization()));
208+ @btime NLS.solve(prob_brusselator_2d, NLS.NewtonRaphson());
209+ @btime NLS.solve(prob_brusselator_2d_sparse, NLS.NewtonRaphson());
210+ @btime NLS.solve(prob_brusselator_2d_sparse, NLS.NewtonRaphson(linsolve = LS.KLUFactorization()));
211211nothing # hide
212212```
213213
@@ -223,7 +223,7 @@ Krylov method. To swap the linear solver out, we use the `linsolve` command and
223223GMRES linear solver.
224224
225225``` @example ill_conditioned_nlprob
226- BenchmarkTools. @btime NLS.solve(prob_brusselator_2d, NLS.NewtonRaphson(linsolve = LS.KrylovJL_GMRES()));
226+ @btime NLS.solve(prob_brusselator_2d, NLS.NewtonRaphson(linsolve = LS.KrylovJL_GMRES()));
227227nothing # hide
228228```
229229
@@ -234,7 +234,7 @@ choices, see the
234234` linsolve ` choices are any valid [ LinearSolve.jl] ( https://linearsolve.sciml.ai/dev/ ) solver.
235235
236236!!! note
237-
237+
238238 Switching to a Krylov linear solver will automatically change the nonlinear problem
239239 solver into Jacobian-free mode, dramatically reducing the memory required. This can be
240240 overridden by adding `concrete_jac=true` to the algorithm.
@@ -254,7 +254,7 @@ import IncompleteLU
254254
255255incompletelu (W, p = nothing ) = IncompleteLU. ilu (W, τ = 50.0 ), LinearAlgebra. I
256256
257- BenchmarkTools . @btime NLS. solve (prob_brusselator_2d_sparse,
257+ @btime NLS. solve (prob_brusselator_2d_sparse,
258258 NLS. NewtonRaphson (linsolve = LS. KrylovJL_GMRES (precs = incompletelu), concrete_jac = true )
259259);
260260nothing # hide
@@ -284,7 +284,7 @@ function algebraicmultigrid(W, p = nothing)
284284 LinearAlgebra.I
285285end
286286
287- BenchmarkTools. @btime NLS.solve(prob_brusselator_2d_sparse,
287+ @btime NLS.solve(prob_brusselator_2d_sparse,
288288 NLS.NewtonRaphson(
289289 linsolve = LS.KrylovJL_GMRES(; precs = algebraicmultigrid), concrete_jac = true
290290 )
@@ -304,7 +304,7 @@ function algebraicmultigrid2(W, p = nothing)
304304 return Pl, LinearAlgebra.I
305305end
306306
307- BenchmarkTools. @btime NLS.solve(
307+ @btime NLS.solve(
308308 prob_brusselator_2d_sparse,
309309 NLS.NewtonRaphson(
310310 linsolve = LS.KrylovJL_GMRES(precs = algebraicmultigrid2), concrete_jac = true
@@ -331,8 +331,8 @@ prob_brusselator_2d_approx_di = NLS.NonlinearProblem(
331331 sparsity = DifferentiationInterface.DenseSparsityDetector(ADTypes.AutoForwardDiff(); atol = 1e-4)),
332332 u0, p; abstol = 1e-10, reltol = 1e-10)
333333
334- BenchmarkTools. @btime NLS.solve(prob_brusselator_2d_exact_tracer, NLS.NewtonRaphson());
335- BenchmarkTools. @btime NLS.solve(prob_brusselator_2d_approx_di, NLS.NewtonRaphson());
334+ @btime NLS.solve(prob_brusselator_2d_exact_tracer, NLS.NewtonRaphson());
335+ @btime NLS.solve(prob_brusselator_2d_approx_di, NLS.NewtonRaphson());
336336nothing # hide
337337```
338338
0 commit comments