Skip to content

Commit 28bd001

Browse files
DanielDoehringSteveMarcoArtianoranocha
authored
Jacobian sparsity pattern via SparseConnectivityTracer and SparseMatrixColorings (#2532)
* Elixir for implicit solver using sparse jacobian * Docstring for new semidiscretize * PR comments * Making the hacks into an extension * Apply suggestions from code review * work * packages * reduce time * work * use sparse ode * comment * be more explicit * try nonlinear * comment * comment * exchange solver * work * comment * comments * comment * rename * comments * Moving the ext back into the elixirs * Adding CI test * Adding CI test for implicit_sparse_jacobian elixir * Update examples/tree_1d_dgsem/elixir_euler_convergence_implicit_sparse_jacobian.jl * Update examples/tree_1d_dgsem/elixir_euler_convergence_implicit_sparse_jacobian.jl * Apply suggestions from code review * Update examples/tree_2d_dgsem/elixir_advection_implicit_sparse_jacobian.jl * comments on constant jacs * move dir * comment * order * restart file * Apply suggestions from code review * compat * remove redundant comments * Elixir for implicit solver using sparse jacobian * Docstring for new semidiscretize * PR comments * Making the hacks into an extension * Apply suggestions from code review * work * packages * reduce time * work * use sparse ode * comment * be more explicit * try nonlinear * comment * comment * exchange solver * work * comment * comments * comment * rename * comments * Moving the ext back into the elixirs * Adding CI test * Adding CI test for implicit_sparse_jacobian elixir * CI tests for both * Other 2 CI tests * Uncomment commented tests and delete 1D convergence_implicit elixir * Replace the test that I accidentally overwrote * Unit test * Update test/test_unit.jl * Update Project.toml * Update examples/tree_2d_dgsem/elixir_advection_implicit_sparse_jacobian.jl * Update examples/tree_2d_dgsem/elixir_advection_implicit_sparse_jacobian.jl * revisit * unit test * repeat comment * linear structure * fmzt * fix unit test * Apply suggestions from code review * Spellcheck * Update examples/tree_2d_dgsem/elixir_advection_implicit_sparse_jacobian.jl * comment * add sparse arrays * try module * rm * try more specific overload * simplify * v * v * Update examples/structured_2d_dgsem/elixir_euler_convergence_implicit_sparse_jacobian.jl Co-authored-by: Marco Artiano <[email protected]> * Update examples/structured_2d_dgsem/elixir_euler_convergence_implicit_sparse_jacobian.jl * Update examples/structured_2d_dgsem/elixir_euler_convergence_implicit_sparse_jacobian.jl * Update examples/tree_2d_dgsem/elixir_advection_implicit_sparse_jacobian.jl * correct comment * simplify * kwargs * adapt * shorten * Update examples/tree_2d_dgsem/elixir_advection_implicit_sparse_jacobian_restart.jl * fmt * simplify * try different warning * warning * test * up * revert * move comment * compat * v * v * v * try plots * v * Update test/Project.toml * module replace * typo * error tol * switch spars detec backend * fmt * clean up * simplify * test no colorvec * add finite diff * typo * docs * add * fmt * correct type * test non-including finite diff * bring back * fix * ext * typo * reduce docs deps * red project * shorten * typo * comment * com * weak dep * Update examples/tree_2d_dgsem/elixir_advection_implicit_sparse_jacobian_restart.jl * Apply suggestions from code review * mention * Apply suggestions from code review Co-authored-by: Hendrik Ranocha <[email protected]> * Apply suggestions from code review Co-authored-by: Hendrik Ranocha <[email protected]> * tspan * shorten * Apply suggestions from code review Co-authored-by: Hendrik Ranocha <[email protected]> * comment * import * Update test/test_structured_2d.jl * fmt * Update docs/literate/src/files/differentiable_programming.jl Co-authored-by: Hendrik Ranocha <[email protected]> * comments * Update src/semidiscretization/semidiscretization.jl Co-authored-by: Hendrik Ranocha <[email protected]> * Apply suggestions from code review Co-authored-by: Hendrik Ranocha <[email protected]> --------- Co-authored-by: Steve <[email protected]> Co-authored-by: Marco Artiano <[email protected]> Co-authored-by: Hendrik Ranocha <[email protected]>
1 parent 89e8e59 commit 28bd001

14 files changed

+570
-9
lines changed

Project.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,14 @@ Convex = "f65535da-76fb-5f13-bab9-19810c17039a"
5959
ECOS = "e2685f51-7e38-5353-a97d-a921fd2c8199"
6060
Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a"
6161
NLsolve = "2774e3e8-f4cf-5e23-947b-6d7e65073b56"
62+
SparseConnectivityTracer = "9f842d2f-2579-4b1d-911e-f412cf18a3f5"
6263

6364
[extensions]
6465
TrixiCUDAExt = "CUDA"
6566
TrixiConvexECOSExt = ["Convex", "ECOS"]
6667
TrixiMakieExt = "Makie"
6768
TrixiNLsolveExt = "NLsolve"
69+
TrixiSparseConnectivityTracerExt = "SparseConnectivityTracer"
6870

6971
[compat]
7072
Accessors = "0.1.36"
@@ -105,6 +107,7 @@ Requires = "1.3"
105107
SciMLBase = "2.67.0"
106108
SimpleUnPack = "1.1"
107109
SparseArrays = "1"
110+
SparseConnectivityTracer = "1.0.1"
108111
StableRNGs = "1.0.2"
109112
StartUpDG = "1.1.5"
110113
Static = "1.1.1"

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ installation and postprocessing procedures. Its features include:
5151
* Relaxation Runge-Kutta methods for entropy-conservative time integration
5252
* Native support for differentiable programming
5353
* Forward mode automatic differentiation via [ForwardDiff.jl](https://github.com/JuliaDiff/ForwardDiff.jl)
54+
* Automatic Jacobian sparsity detection via [SparseConnectivityTracer.jl](https://github.com/adrhill/SparseConnectivityTracer.jl)
5455
* Periodic and weakly-enforced boundary conditions
5556
* Multiple governing equations:
5657
* Compressible Euler equations

docs/Project.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
[deps]
22
Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e"
3+
ADTypes = "47edcb42-4c32-4615-8424-f2b9edc5f35b"
34
CairoMakie = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0"
45
Changelog = "5217a498-cd5d-4ec6-b8c2-9b85a09b6e3e"
56
Convex = "f65535da-76fb-5f13-bab9-19810c17039a"
@@ -13,9 +14,12 @@ Measurements = "eff96d63-e80a-5855-80a2-b1b0885c5ab7"
1314
NLsolve = "2774e3e8-f4cf-5e23-947b-6d7e65073b56"
1415
OrdinaryDiffEqLowOrderRK = "1344f307-1e59-4825-a18e-ace9aa3fa4c6"
1516
OrdinaryDiffEqLowStorageRK = "b0944070-b475-4768-8dec-fb6eb410534d"
17+
OrdinaryDiffEqSDIRK = "2d112036-d095-4a1e-ab9a-08536f3ecdbf"
1618
OrdinaryDiffEqSSPRK = "669c94d9-1f4b-4b64-b377-1aa079aa2388"
1719
OrdinaryDiffEqTsit5 = "b1df2697-797e-41e3-8120-5422d3b24e4a"
1820
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
21+
SparseConnectivityTracer = "9f842d2f-2579-4b1d-911e-f412cf18a3f5"
22+
SparseMatrixColorings = "0a514795-09f3-496d-8182-132a7b665d35"
1923
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
2024
Trixi = "a7f1ee26-1774-49b1-8366-f1abc58fbfcb"
2125
Trixi2Vtk = "bc1476a1-1ca6-4cc3-950b-c312b255ff95"
@@ -26,6 +30,7 @@ path = ".."
2630

2731
[compat]
2832
Adapt = "4"
33+
ADTypes = "1.11"
2934
CairoMakie = "0.12, 0.13, 0.14, 0.15"
3035
Changelog = "1.1"
3136
Convex = "0.16"
@@ -39,9 +44,12 @@ Measurements = "2.5"
3944
NLsolve = "4.5.1"
4045
OrdinaryDiffEqLowOrderRK = "1.2"
4146
OrdinaryDiffEqLowStorageRK = "1.2"
47+
OrdinaryDiffEqSDIRK = "1.1"
4248
OrdinaryDiffEqSSPRK = "1.2"
4349
OrdinaryDiffEqTsit5 = "1.1"
4450
Plots = "1.9"
51+
SparseConnectivityTracer = "1.0.1"
52+
SparseMatrixColorings = "0.4.21"
4553
Test = "1"
4654
Trixi2Vtk = "0.3.16"
4755
TrixiBase = "0.1.1"

docs/literate/src/files/differentiable_programming.jl

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,94 @@ relative_difference = norm(J_fd - J_ad) / size(J_fd, 1)
401401

402402
# This discrepancy is of the expected order of magnitude for central finite difference approximations.
403403

404+
# ## Automatic Jacobian sparsity detection and coloring
405+
406+
# When solving large sparse nonlinear ODE systems originating from spatial discretizations
407+
# with compact stencils such as the DG method with implicit time integrators,
408+
# exploiting the sparsity of the Jacobian can lead to significant speedups in the Newton-Raphson solver.
409+
# Similarly, steady-state problems can also be solved faster.
410+
411+
# [Trixi.jl](https://github.com/trixi-framework/Trixi.jl) supports efficient Jacobian computations by leveraging the
412+
# [SparseConnectivityTracer.jl](https://github.com/adrhill/SparseConnectivityTracer.jl)
413+
# and [SparseMatrixColorings.jl](https://github.com/gdalle/SparseMatrixColorings.jl) packages.
414+
# These tools allow to detect the sparsity pattern of the Jacobian and compute the
415+
# optional coloring vector for efficient Jacobian evaluations.
416+
# These are then handed over to the ODE solver from [OrdinaryDiffEq.jl](https://github.com/SciML/OrdinaryDiffEq.jl).
417+
418+
# Below is a minimal example in 1D, showing how to use these packages with Trixi.jl.
419+
# First, we define the the `equation` and `mesh` as for an ordinary simulation:
420+
421+
using Trixi
422+
423+
advection_velocity = 1.0
424+
equation = LinearScalarAdvectionEquation1D(advection_velocity)
425+
426+
mesh = TreeMesh((-1.0,), (1.0,), initial_refinement_level = 4, n_cells_max = 10^4)
427+
428+
# We define the basic floating point type used for the actual simulation
429+
# and construct the solver:
430+
float_type = Float64
431+
solver = DGSEM(polydeg = 3, surface_flux = flux_godunov, RealT = float_type)
432+
433+
# Next, we set up the sparsity detection. For this we need
434+
using SparseConnectivityTracer # For Jacobian sparsity pattern
435+
436+
# We use the [global `TracerSparsityDetector()`](https://adrianhill.de/SparseConnectivityTracer.jl/stable/user/global_vs_local/) here.
437+
jac_detector = TracerSparsityDetector()
438+
439+
# Next, we retrieve the right element type corresponding to `float_type` for the Jacobian sparsity detection.
440+
# For more details, see the API documentation of
441+
# [`jacobian_eltype`](https://adrianhill.de/SparseConnectivityTracer.jl/stable/user/api/#SparseConnectivityTracer.jacobian_eltype).
442+
jac_eltype = jacobian_eltype(float_type, jac_detector)
443+
444+
# Now we can construct the semidiscretization for sparsity detection with `jac_eltype` as the
445+
# datatype for the working arrays and helper datastructures.
446+
semi_jac_type = SemidiscretizationHyperbolic(mesh, equation,
447+
initial_condition_convergence_test, solver,
448+
uEltype = jac_eltype) # Supply sparsity detection datatype here
449+
450+
tspan = (0.0, 1.0) # Re-used later in `rhs!` evaluation
451+
ode_jac_type = semidiscretize(semi_jac_type, tspan)
452+
u0_ode = ode_jac_type.u0
453+
du_ode = similar(u0_ode)
454+
455+
# Wrap the RHS for sparsity detection to match the expected signature f!(du, u) required by
456+
# [`jacobian_sparsity`](https://adrianhill.de/SparseConnectivityTracer.jl/stable/user/api/#ADTypes.jacobian_sparsity).
457+
rhs_wrapped! = (du, u) -> Trixi.rhs!(du, u, semi_jac_type, tspan[1])
458+
jac_prototype = jacobian_sparsity(rhs_wrapped!, du_ode, u0_ode, jac_detector)
459+
460+
# Optionally, we can also compute the coloring vector to reduce Jacobian evaluations
461+
# to `1 + maximum(coloring_vec)` for finite differencing and `maximum(coloring_vec)` for algorithmic differentiation.
462+
# For this, we need
463+
using SparseMatrixColorings
464+
465+
# We partition by columns as we are using finite differencing here.
466+
# One would also partition by columns if forward-based algorithmic differentiation were used,
467+
# and only partition by rows if reverse-mode AD were used.
468+
# See also [the documentation of the now deprecated SparseDiffTools.jl](https://github.com/JuliaDiff/SparseDiffTools.jl?tab=readme-ov-file#matrix-coloring) package,
469+
# the predecessor in spirit to SparseConnectivityTracer.jl and SparseMatrixColorings.jl, for more information.
470+
coloring_prob = ColoringProblem(; structure = :nonsymmetric, partition = :column)
471+
coloring_alg = GreedyColoringAlgorithm(; decompression = :direct)
472+
coloring_result = coloring(jac_prototype, coloring_prob, coloring_alg)
473+
coloring_vec = column_colors(coloring_result)
474+
475+
# Now, set up the actual semidiscretization for the simulation.
476+
# The datatype is automatically retrieved from the solver (in this case `float_type = Float64`).
477+
semi_float_type = SemidiscretizationHyperbolic(mesh, equation,
478+
initial_condition_convergence_test, solver)
479+
# Supply the sparse Jacobian prototype and the optional coloring vector.
480+
# Internally, an [`ODEFunction`](https://docs.sciml.ai/DiffEqDocs/stable/types/ode_types/#SciMLBase.ODEFunction)
481+
# with `jac_prototype = jac_prototype` and `colorvec = coloring_vec` is created.
482+
ode_jac_sparse = semidiscretize(semi_float_type, tspan,
483+
jac_prototype = jac_prototype,
484+
colorvec = coloring_vec)
485+
486+
# You can now solve the ODE problem efficiently with an implicit solver.
487+
# Currently we are bound to finite differencing here.
488+
using OrdinaryDiffEqSDIRK, ADTypes
489+
sol = solve(ode_jac_sparse, TRBDF2(; autodiff = AutoFiniteDiff()), dt = 0.1,
490+
save_everystep = false)
491+
404492
# ## Linear systems
405493

406494
# When a linear PDE is discretized using a linear scheme such as a standard DG method,

docs/src/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ installation and postprocessing procedures. Its features include:
4747
* Relaxation Runge-Kutta methods for entropy-conservative time integration
4848
* Native support for differentiable programming
4949
* Forward mode automatic differentiation via [ForwardDiff.jl](https://github.com/JuliaDiff/ForwardDiff.jl)
50+
* Automatic Jacobian sparsity detection via [SparseConnectivityTracer.jl](https://github.com/adrhill/SparseConnectivityTracer.jl)
5051
* Periodic and weakly-enforced boundary conditions
5152
* Multiple governing equations:
5253
* Compressible Euler equations
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
using Trixi
2+
using SparseConnectivityTracer # For obtaining the Jacobian sparsity pattern
3+
using SparseMatrixColorings # For obtaining the coloring vector
4+
using OrdinaryDiffEqSDIRK, ADTypes
5+
6+
###############################################################################
7+
### solver and equations ###
8+
9+
# For sparsity detection we can only use `flux_lax_friedrichs` at the moment since this is
10+
# `if`-clause free (although it contains `min` and `max` operations).
11+
# The sparsity pattern, however, should be the same for other (two-point) fluxes as well.
12+
surface_flux = flux_lax_friedrichs
13+
solver = DGSEM(polydeg = 3, surface_flux = surface_flux)
14+
15+
equations = CompressibleEulerEquations2D(1.4)
16+
17+
###############################################################################
18+
### mesh ###
19+
20+
# Mapping as described in https://arxiv.org/abs/2012.12040,
21+
# reduced to 2D on [0, 2]^2 instead of [0, 3]^3
22+
function mapping(xi_, eta_)
23+
# Transform input variables between -1 and 1 onto [0,2]
24+
xi = xi_ + 1
25+
eta = eta_ + 1
26+
27+
y = eta + 1 / 4 * (cos(pi * (xi - 1)) *
28+
cos(0.5 * pi * (eta - 1)))
29+
30+
x = xi + 1 / 4 * (cos(0.5 * pi * (xi - 1)) *
31+
cos(2 * pi * (y - 1)))
32+
33+
return SVector(x, y)
34+
end
35+
cells_per_dimension = (16, 16)
36+
mesh = StructuredMesh(cells_per_dimension, mapping)
37+
38+
###############################################################################
39+
### semidiscretization for sparsity detection ###
40+
41+
jac_detector = TracerSparsityDetector()
42+
# We need to construct the semidiscretization with the correct
43+
# sparsity-detection ready datatype, which is retrieved here
44+
jac_eltype = jacobian_eltype(real(solver), jac_detector)
45+
46+
# Semidiscretization for sparsity pattern detection
47+
semi_jac_type = SemidiscretizationHyperbolic(mesh, equations,
48+
initial_condition_convergence_test,
49+
solver,
50+
source_terms = source_terms_convergence_test,
51+
uEltype = jac_eltype) # Need to supply Jacobian element type
52+
53+
tspan = (0.0, 5.0) # Re-used for wrapping `rhs` below
54+
55+
# Call `semidiscretize` to create the ODE problem to have access to the
56+
# initial condition based on which the sparsity pattern is computed
57+
ode_jac_type = semidiscretize(semi_jac_type, tspan)
58+
u0_ode = ode_jac_type.u0
59+
du_ode = similar(u0_ode)
60+
61+
###############################################################################
62+
### Compute the Jacobian sparsity pattern ###
63+
64+
# Wrap the `Trixi.rhs!` function to match the signature `f!(du, u)`, see
65+
# https://adrianhill.de/SparseConnectivityTracer.jl/stable/user/api/#ADTypes.jacobian_sparsity
66+
rhs_wrapped! = (du_ode, u0_ode) -> Trixi.rhs!(du_ode, u0_ode, semi_jac_type, tspan[1])
67+
68+
jac_prototype = jacobian_sparsity(rhs_wrapped!, du_ode, u0_ode, jac_detector)
69+
70+
# For most efficient solving we also want the coloring vector
71+
72+
coloring_prob = ColoringProblem(; structure = :nonsymmetric, partition = :column)
73+
coloring_alg = GreedyColoringAlgorithm(; decompression = :direct)
74+
coloring_result = coloring(jac_prototype, coloring_prob, coloring_alg)
75+
coloring_vec = column_colors(coloring_result)
76+
77+
###############################################################################
78+
### sparsity-aware semidiscretization and ode ###
79+
80+
# Semidiscretization for actual simulation
81+
semi_float_type = SemidiscretizationHyperbolic(mesh, equations,
82+
initial_condition_convergence_test,
83+
solver,
84+
source_terms = source_terms_convergence_test)
85+
86+
# Supply Jacobian prototype and coloring vector to the semidiscretization
87+
ode_jac_sparse = semidiscretize(semi_float_type, tspan,
88+
jac_prototype = jac_prototype,
89+
colorvec = coloring_vec)
90+
# using "dense" `ode = semidiscretize(semi_float_type, tspan)`
91+
# is essentially infeasible, even single step takes ages!
92+
93+
###############################################################################
94+
### callbacks & solve ###
95+
96+
summary_callback = SummaryCallback()
97+
analysis_callback = AnalysisCallback(semi_float_type, interval = 50)
98+
alive_callback = AliveCallback(alive_interval = 3)
99+
100+
# Note: No `stepsize_callback` due to implicit solver
101+
callbacks = CallbackSet(summary_callback, analysis_callback, alive_callback)
102+
103+
sol = solve(ode_jac_sparse,
104+
# Default `AutoForwardDiff()` is not yet working, see
105+
# https://github.com/trixi-framework/Trixi.jl/issues/2369
106+
Kvaerno4(; autodiff = AutoFiniteDiff());
107+
dt = 0.05, save_everystep = false, callback = callbacks);
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
using Trixi
2+
using SparseConnectivityTracer # For obtaining the Jacobian sparsity pattern
3+
using SparseMatrixColorings # For obtaining the coloring vector
4+
using OrdinaryDiffEqSDIRK, ADTypes
5+
6+
###############################################################################
7+
### equation, solver, mesh ###
8+
9+
advection_velocity = (0.2, -0.7)
10+
equation = LinearScalarAdvectionEquation2D(advection_velocity)
11+
12+
solver = DGSEM(polydeg = 3, surface_flux = flux_godunov)
13+
14+
coordinates_min = (-1.0, -1.0)
15+
coordinates_max = (1.0, 1.0)
16+
17+
mesh = TreeMesh(coordinates_min, coordinates_max,
18+
initial_refinement_level = 4,
19+
n_cells_max = 30_000)
20+
21+
###############################################################################
22+
### semidiscretization for sparsity detection ###
23+
24+
jac_detector = TracerSparsityDetector()
25+
# We need to construct the semidiscretization with the correct
26+
# sparsity-detection ready datatype, which is retrieved here
27+
jac_eltype = jacobian_eltype(real(solver), jac_detector)
28+
29+
# Semidiscretization for sparsity pattern detection
30+
semi_jac_type = SemidiscretizationHyperbolic(mesh, equation,
31+
initial_condition_convergence_test, solver,
32+
uEltype = jac_eltype) # Need to supply Jacobian element type
33+
34+
tspan = (0.0, 1.0) # Re-used for wrapping `rhs` below
35+
36+
# Call `semidiscretize` to create the ODE problem to have access to the
37+
# initial condition based on which the sparsity pattern is computed
38+
ode_jac_type = semidiscretize(semi_jac_type, tspan)
39+
u0_ode = ode_jac_type.u0
40+
du_ode = similar(u0_ode)
41+
42+
###############################################################################
43+
### Compute the Jacobian sparsity pattern ###
44+
45+
# Wrap the `Trixi.rhs!` function to match the signature `f!(du, u)`, see
46+
# https://adrianhill.de/SparseConnectivityTracer.jl/stable/user/api/#ADTypes.jacobian_sparsity
47+
rhs_wrapped! = (du_ode, u0_ode) -> Trixi.rhs!(du_ode, u0_ode, semi_jac_type, tspan[1])
48+
49+
jac_prototype = jacobian_sparsity(rhs_wrapped!, du_ode, u0_ode, jac_detector)
50+
51+
# For most efficient solving we also want the coloring vector
52+
53+
coloring_prob = ColoringProblem(; structure = :nonsymmetric, partition = :column)
54+
coloring_alg = GreedyColoringAlgorithm(; decompression = :direct)
55+
coloring_result = coloring(jac_prototype, coloring_prob, coloring_alg)
56+
coloring_vec = column_colors(coloring_result)
57+
58+
###############################################################################
59+
### sparsity-aware semidiscretization and ode ###
60+
61+
# Semidiscretization for actual simulation. `eEltype` is here retrieved from `solver`
62+
semi_float_type = SemidiscretizationHyperbolic(mesh, equation,
63+
initial_condition_convergence_test,
64+
solver)
65+
66+
# Supply Jacobian prototype and coloring vector to the semidiscretization
67+
ode_jac_sparse = semidiscretize(semi_float_type, tspan,
68+
jac_prototype = jac_prototype,
69+
colorvec = coloring_vec)
70+
# using "dense" `ode = semidiscretize(semi_float_type, tspan)` is 10-15 times slower!
71+
72+
###############################################################################
73+
### callbacks & solve ###
74+
75+
summary_callback = SummaryCallback()
76+
analysis_callback = AnalysisCallback(semi_float_type, interval = 10)
77+
save_restart = SaveRestartCallback(interval = 100,
78+
save_final_restart = true)
79+
80+
# Note: No `stepsize_callback` due to (implicit) solver with adaptive timestep control
81+
callbacks = CallbackSet(summary_callback, analysis_callback, save_restart)
82+
83+
###############################################################################
84+
### solve the ODE problem ###
85+
86+
sol = solve(ode_jac_sparse,
87+
# Default `AutoForwardDiff()` is not yet working, see
88+
# https://github.com/trixi-framework/Trixi.jl/issues/2369
89+
TRBDF2(; autodiff = AutoFiniteDiff());
90+
dt = 0.1, save_everystep = false, callback = callbacks);

0 commit comments

Comments
 (0)