Skip to content

Commit e1dad26

Browse files
committed
improve predondtioner text
1 parent 9804397 commit e1dad26

File tree

1 file changed

+6
-8
lines changed

1 file changed

+6
-8
lines changed

docs/src/catalyst_applications/ode_simulation_performance.md

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -131,15 +131,17 @@ nothing # hide
131131
```
132132
A full list of potential linear solvers can be found [here](https://docs.sciml.ai/LinearSolve/dev/solvers/solvers/#Full-List-of-Methods), however, the default choice typically performs well.
133133

134-
A unique approach to the linear solvers is to use a Jacobian-free Newton-Krylov method. These do not actually compute the Jacobian, but rather *the effect of multiplying it with a vector*. They are typically advantageous for large systems (with large Jacobians), and can be designated using the `KrylovJL_GMRES` linear solver:
134+
A unique approach to the linear solvers is to use a matrix-free Newton-Krylov method. These do not actually compute the Jacobian, but rather *the effect of multiplying it with a vector*. They are typically advantageous for large systems (with large Jacobians), and can be designated using the `KrylovJL_GMRES` linear solver:
135135
```@example ode_simulation_performance_3
136136
solve(oprob, Rodas5P(linsolve = KrylovJL_GMRES()))
137137
nothing # hide
138138
```
139139
Since these methods do not depend on a Jacobian, certain Jacobian options (such as [computing it symbolically](@ref ode_simulation_performance_symbolic_jacobian)) are irrelevant to them.
140140

141141
### [Designating preconditioners for Jacobian-free linear solvers](@ref ode_simulation_performance_preconditioners)
142-
When an implicit method solves a linear equation through an iterative method, the rate of convergence depends on the numerical properties of the matrix defining the linear system. To speed up convergence, a [*preconditioner*](https://en.wikipedia.org/wiki/Preconditioner) can be applied to both sides of the linear equation, attempting to create an equation that converges faster. In practice, preconditioners are implemented as functions with a specific set of arguments. How to implement these is non-trivial, and we recommend reading OrdinaryDiffEq's documentation pages [here](https://docs.sciml.ai/DiffEqDocs/stable/features/linear_nonlinear/#Preconditioners:-precs-Specification) and [here](https://docs.sciml.ai/DiffEqDocs/stable/tutorials/advanced_ode_example/#Adding-a-Preconditioner). In this example, we will define an [Incomplete LU](https://en.wikipedia.org/wiki/Incomplete_LU_factorization) preconditioner (which requires the [IncompleteLU.jl](https://github.com/haampie/IncompleteLU.jl) package):
142+
When an implicit method solves a linear equation through an iterative method, the rate of convergence depends on the numerical properties of the matrix defining the linear system. To speed up convergence, a [*preconditioner*](https://en.wikipedia.org/wiki/Preconditioner) can be applied to both sides of the linear equation, attempting to create an equation that converges faster. Preconditioners are only actually relevant when using matrix-free Krylov methods.
143+
144+
In practice, preconditioners are implemented as functions with a specific set of arguments. How to implement these is non-trivial, and we recommend reading OrdinaryDiffEq's documentation pages [here](https://docs.sciml.ai/DiffEqDocs/stable/features/linear_nonlinear/#Preconditioners:-precs-Specification) and [here](https://docs.sciml.ai/DiffEqDocs/stable/tutorials/advanced_ode_example/#Adding-a-Preconditioner). In this example, we will define an [Incomplete LU](https://en.wikipedia.org/wiki/Incomplete_LU_factorization) preconditioner (which requires the [IncompleteLU.jl](https://github.com/haampie/IncompleteLU.jl) package):
143145
```@example ode_simulation_performance_3
144146
using IncompleteLU
145147
function incompletelu(W, du, u, p, t, newW, Plprev, Prprev, solverdata)
@@ -154,16 +156,12 @@ nothing # hide
154156
```
155157
Next, `incompletelu` can be supplied to our solver using the `precs` argument:
156158
```@example ode_simulation_performance_3
157-
solve(oprob, Rodas5P(precs = incompletelu))
158-
nothing # hide
159-
```
160-
Finally, we note that since matrix-free linear solvers (like `KrylovJL_GMRES`) by default do not build a Jacobian. Hence, if we want to use them with a preconditioner we must tell them to build it. This can be done using the `concrete_jacobian=true` option:
161-
```@example ode_simulation_performance_3
162159
solve(oprob, Rodas5P(linsolve = KrylovJL_GMRES(), precs = incompletelu, concrete_jac=true))
163160
nothing # hide
164161
```
162+
Finally, we note that when using preconditioners with a matrix free method (like `KrylovJL_GMRES`, which is also the only case when these are relevant), the `concrete_jac=true` argument is required.
165163

166-
Generally, the use of preconditioners is only recommended for advanced users who are familiar with the concepts. However, for large systems, if performance is essential, they can still be worth looking into.
164+
Generally, the use of preconditioners is only recommended for advanced users who are familiar with the concepts. However, for large systems, if performance is essential, they can be worth looking into.
167165

168166
## [Parallelisation on CPUs and GPUs](@id ode_simulation_performance_parallelisation)
169167
Whenever an ODE is simulated a large number of times (e.g. when investigating its behaviour for different parameter values), the best way to improve performance is to [parallelise the simulation over several processing units](https://en.wikipedia.org/wiki/Parallel_computing). Indeed, an advantage of the Julia programming language is that it was designed after the advent of parallel computing, making it well-suited for this task. Roughly, parallelisation can be divided into parallelisation on [CPUs](https://en.wikipedia.org/wiki/Central_processing_unit) and on [GPUs](https://en.wikipedia.org/wiki/General-purpose_computing_on_graphics_processing_units). CPU parallelisation is most straightforward, while GPU parallelisation requires specialised ODE solvers (which Catalyst have access to).

0 commit comments

Comments
 (0)