Using the an implicit solver based on Ariadne with Trixi.jl

using Trixi
using Theseus
using CairoMakie
using LinearAlgebra
import Ariadne: JacobianOperator

Notes: Must disable both Polyester and LoopVectorization for Enzyme to be able to differentiate Trixi.jl

LocalPreferences.jl

[Trixi]
loop_vectorization = false
backend = "static"
@assert Trixi._PREFERENCE_THREADING !== :polyester
@assert !Trixi._PREFERENCE_LOOPVECTORIZATION

Load Trixi Example

trixi_include(@__MODULE__, joinpath(examples_dir(), "tree_2d_dgsem", "elixir_advection_basic.jl"), sol = nothing);

u = copy(ode.u0)
du = zero(ode.u0)
res = zero(ode.u0)

F! = Theseus.nonlinear_problem(Theseus.ImplicitEuler(), ode.f)
J = JacobianOperator(F!, res, u, (ode.u0, 1.0, du, ode.p, 0.0, (), 1))

out = zero(u)
v = zero(u)

# precompile
mul!(u, J, v)
F!(res, u, (ode.u0, 1.0, du, ode.p, 0.0, (), 1))

@time mul!(u, J, v)
@time F!(res, u, (ode.u0, 1.0, du, ode.p, 0.0, (), 1))
[ Info: You just called `trixi_include`. Julia may now compile the code, please be patient.
  0.000176 seconds (79 allocations: 7.844 KiB)
  0.000136 seconds (7 allocations: 352 bytes)

Cost of time(mul!) ≈ 2 * time(F!)

Solve using ODE interface

sol_trbdf2 = solve(
    ode, Theseus.TRBDF2();
    dt = 1.0, # solve needs some value here but it will be overwritten by the stepsize_callback
    ode_default_options()..., callback = callbacks,
    # verbose=1,
    krylov_algo = :gmres,
    # krylov_kwargs=(;verbose=1)
);

████████╗██████╗ ██╗██╗  ██╗██╗
╚══██╔══╝██╔══██╗██║╚██╗██╔╝██║
   ██║   ██████╔╝██║ ╚███╔╝ ██║
   ██║   ██╔══██╗██║ ██╔██╗ ██║
   ██║   ██║  ██║██║██╔╝ ██╗██║
   ╚═╝   ╚═╝  ╚═╝╚═╝╚═╝  ╚═╝╚═╝

┌──────────────────────────────────────────────────────────────────────────────────────────────────┐
│ SemidiscretizationHyperbolic                                                                     │
│ ════════════════════════════                                                                     │
│ #spatial dimensions: ……………………………………… 2                                                           │
│ mesh: ……………………………………………………………………………… TreeMesh{2, Trixi.SerialTree{2, Float64}} with length 341   │
│ equations: ………………………………………………………………… LinearScalarAdvectionEquation2D                             │
│ initial condition: …………………………………………… initial_condition_convergence_test                          │
│ boundary conditions: ……………………………………… Trixi.BoundaryConditionPeriodic                             │
│ source terms: ………………………………………………………… nothing                                                     │
│ solver: ………………………………………………………………………… DG                                                          │
│ total #DOFs per field: ………………………………… 4096                                                        │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘

┌──────────────────────────────────────────────────────────────────────────────────────────────────┐
│ TreeMesh{2, Trixi.SerialTree{2, Float64}}                                                        │
│ ═════════════════════════════════════════                                                        │
│ center: ………………………………………………………………………… [0.0, 0.0]                                                  │
│ length: ………………………………………………………………………… 2.0                                                         │
│ periodicity: …………………………………………………………… (true, true)                                                │
│ current #cells: …………………………………………………… 341                                                         │
│ #leaf-cells: …………………………………………………………… 256                                                         │
│ current capacity: ……………………………………………… 341                                                         │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘

┌──────────────────────────────────────────────────────────────────────────────────────────────────┐
│ LinearScalarAdvectionEquation2D                                                                  │
│ ═══════════════════════════════                                                                  │
│ #variables: ……………………………………………………………… 1                                                           │
│ │ variable 1: ………………………………………………………… scalar                                                      │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘

┌──────────────────────────────────────────────────────────────────────────────────────────────────┐
│ DG{Float64}                                                                                      │
│ ═══════════                                                                                      │
│ basis: …………………………………………………………………………… LobattoLegendreBasis{Float64}(polydeg=3)                    │
│ mortar: ………………………………………………………………………… LobattoLegendreMortarL2{Float64}(polydeg=3)                 │
│ surface integral: ……………………………………………… SurfaceIntegralWeakForm                                     │
│ │ surface flux: …………………………………………………… FluxLaxFriedrichs(max_abs_speed)                            │
│ volume integral: ………………………………………………… VolumeIntegralWeakForm                                      │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘

┌──────────────────────────────────────────────────────────────────────────────────────────────────┐
│ AnalysisCallback                                                                                 │
│ ════════════════                                                                                 │
│ interval: …………………………………………………………………… 100                                                         │
│ analyzer: …………………………………………………………………… LobattoLegendreAnalyzer{Float64}(polydeg=6)                 │
│ │ error 1: ………………………………………………………………… l2_error                                                    │
│ │ error 2: ………………………………………………………………… linf_error                                                  │
│ │ integral 1: ………………………………………………………… entropy_timederivative                                      │
│ save analysis to file: ………………………………… no                                                          │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘

┌──────────────────────────────────────────────────────────────────────────────────────────────────┐
│ SaveSolutionCallback                                                                             │
│ ════════════════════                                                                             │
│ interval: …………………………………………………………………… 100                                                         │
│ solution variables: ………………………………………… cons2prim                                                   │
│ save initial solution: ………………………………… yes                                                         │
│ save final solution: ……………………………………… yes                                                         │
│ output directory: ……………………………………………… /home/runner/work/Ariadne.jl/…e.jl/docs/build/generated/out │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘

┌──────────────────────────────────────────────────────────────────────────────────────────────────┐
│ StepsizeCallback                                                                                 │
│ ════════════════                                                                                 │
│ CFL Hyperbolic: …………………………………………………… Returns{Float64}(1.6)                                       │
│ CFL Parabolic: ……………………………………………………… Returns{Float64}(0.0)                                       │
│ Interval: …………………………………………………………………… 1                                                           │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘

┌──────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Time integration                                                                                 │
│ ════════════════                                                                                 │
│ Start time: ……………………………………………………………… 0.0                                                         │
│ Final time: ……………………………………………………………… 1.0                                                         │
│ time integrator: ………………………………………………… TRBDF2                                                      │
│ adaptive: …………………………………………………………………… false                                                       │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Environment information                                                                          │
│ ═══════════════════════                                                                          │
│ #threads: …………………………………………………………………… 1                                                           │
│ threading backend: …………………………………………… static                                                      │
│ LoopVectorization: …………………………………………… disabled                                                    │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘

────────────────────────────────────────────────────────────────────────────────────────────────────
 Simulation running 'LinearScalarAdvectionEquation2D' with DGSEM(polydeg=3)
────────────────────────────────────────────────────────────────────────────────────────────────────
 #timesteps:                  0                run time:       1.10077555e+00 s
 Δt:             1.00000000e+00                └── GC time:    0.00000000e+00 s (0.000%)
 sim. time:      0.00000000e+00 (0.000%)       time/DOF/rhs!:  2.56894531e-08 s
                                               PID:                   Inf s
 #DOFs per field:          4096                alloc'd memory:        608.310 MiB
 #elements:                 256                device memory:           0.000 MiB

 Variable:       scalar
 L2 error:       3.94120825e-06
 Linf error:     1.23670425e-05
 ∑∂S/∂U ⋅ Uₜ :  -2.19124035e-16
────────────────────────────────────────────────────────────────────────────────────────────────────


────────────────────────────────────────────────────────────────────────────────────────────────────
 Simulation running 'LinearScalarAdvectionEquation2D' with DGSEM(polydeg=3)
────────────────────────────────────────────────────────────────────────────────────────────────────
 #timesteps:                 18                run time:       2.46422408e+01 s
 Δt:             5.55555556e-02                └── GC time:    2.60510290e-01 s (1.057%)
 sim. time:      1.00000000e+00 (100.000%)     time/DOF/rhs!:  2.11587047e-08 s
                                               PID:            1.06816836e-05 s
 #DOFs per field:          4096                alloc'd memory:        379.768 MiB
 #elements:                 256                device memory:           0.000 MiB

 Variable:       scalar
 L2 error:       1.71224434e-04
 Linf error:     2.52822142e-04
 ∑∂S/∂U ⋅ Uₜ :  -1.97551223e-09
────────────────────────────────────────────────────────────────────────────────────────────────────

────────────────────────────────────────────────────────────────────────────────────
             Trixi.jl                      Time                    Allocations
                                  ───────────────────────   ────────────────────────
        Tot / % measured:              25.0s /   5.0%           1.17GiB /   2.5%

Section                   ncalls     time    %tot     avg     alloc    %tot      avg
────────────────────────────────────────────────────────────────────────────────────
I/O                            3    987ms   78.6%   329ms   11.8MiB   38.8%  3.94MiB
  ~I/O~                        3    885ms   70.5%   295ms   8.08MiB   26.5%  2.69MiB
  save solution                2   94.6ms    7.5%  47.3ms   3.14MiB   10.3%  1.57MiB
  get element variables        2   7.25ms    0.6%  3.63ms    622KiB    2.0%   311KiB
  get node variables           2    711ns    0.0%   356ns     0.00B    0.0%    0.00B
  save mesh                    2    421ns    0.0%   210ns     0.00B    0.0%    0.00B
analyze solution               2    222ms   17.7%   111ms   18.6MiB   61.1%  9.31MiB
rhs!                         533   46.1ms    3.7%  86.5μs   4.78KiB    0.0%    9.19B
  volume integral            533   31.3ms    2.5%  58.8μs     0.00B    0.0%    0.00B
  interface flux             533   4.24ms    0.3%  7.96μs     0.00B    0.0%    0.00B
  surface integral           533   3.31ms    0.3%  6.21μs     0.00B    0.0%    0.00B
  prolong2interfaces         533   3.22ms    0.3%  6.03μs     0.00B    0.0%    0.00B
  Jacobian                   533   2.79ms    0.2%  5.23μs     0.00B    0.0%    0.00B
  ~rhs!~                     533    542μs    0.0%  1.02μs   4.78KiB    0.0%    9.19B
  reset ∂u/∂t                533    527μs    0.0%   989ns     0.00B    0.0%    0.00B
  prolong2mortars            533   43.5μs    0.0%  81.6ns     0.00B    0.0%    0.00B
  prolong2boundaries         533   30.5μs    0.0%  57.2ns     0.00B    0.0%    0.00B
  mortar flux                533   25.3μs    0.0%  47.5ns     0.00B    0.0%    0.00B
  boundary flux              533   16.6μs    0.0%  31.1ns     0.00B    0.0%    0.00B
  source terms               533   15.6μs    0.0%  29.3ns     0.00B    0.0%    0.00B
calculate dt                  19   16.7μs    0.0%   877ns   2.67KiB    0.0%     144B
────────────────────────────────────────────────────────────────────────────────────

Plot the solution

We have to manually convert the sol since Theseus has it's own lightweight solution type.

plot(Trixi.PlotData2DTriangulated(sol_trbdf2.u[end], sol_trbdf2.prob.p))

Solve using OrdinaryDiffEqSDIRK

import OrdinaryDiffEqSDIRK
import DifferentiationInterface: AutoFiniteDiff
sol_sdrik = solve(
    ode, OrdinaryDiffEqSDIRK.TRBDF2(autodiff = AutoFiniteDiff());
    dt = 1.0, # solve needs some value here but it will be overwritten by the stepsize_callback
    ode_default_options()..., callback = callbacks,
    adaptive = false
);

████████╗██████╗ ██╗██╗  ██╗██╗
╚══██╔══╝██╔══██╗██║╚██╗██╔╝██║
   ██║   ██████╔╝██║ ╚███╔╝ ██║
   ██║   ██╔══██╗██║ ██╔██╗ ██║
   ██║   ██║  ██║██║██╔╝ ██╗██║
   ╚═╝   ╚═╝  ╚═╝╚═╝╚═╝  ╚═╝╚═╝

┌──────────────────────────────────────────────────────────────────────────────────────────────────┐
│ SemidiscretizationHyperbolic                                                                     │
│ ════════════════════════════                                                                     │
│ #spatial dimensions: ……………………………………… 2                                                           │
│ mesh: ……………………………………………………………………………… TreeMesh{2, Trixi.SerialTree{2, Float64}} with length 341   │
│ equations: ………………………………………………………………… LinearScalarAdvectionEquation2D                             │
│ initial condition: …………………………………………… initial_condition_convergence_test                          │
│ boundary conditions: ……………………………………… Trixi.BoundaryConditionPeriodic                             │
│ source terms: ………………………………………………………… nothing                                                     │
│ solver: ………………………………………………………………………… DG                                                          │
│ total #DOFs per field: ………………………………… 4096                                                        │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘

┌──────────────────────────────────────────────────────────────────────────────────────────────────┐
│ TreeMesh{2, Trixi.SerialTree{2, Float64}}                                                        │
│ ═════════════════════════════════════════                                                        │
│ center: ………………………………………………………………………… [0.0, 0.0]                                                  │
│ length: ………………………………………………………………………… 2.0                                                         │
│ periodicity: …………………………………………………………… (true, true)                                                │
│ current #cells: …………………………………………………… 341                                                         │
│ #leaf-cells: …………………………………………………………… 256                                                         │
│ current capacity: ……………………………………………… 341                                                         │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘

┌──────────────────────────────────────────────────────────────────────────────────────────────────┐
│ LinearScalarAdvectionEquation2D                                                                  │
│ ═══════════════════════════════                                                                  │
│ #variables: ……………………………………………………………… 1                                                           │
│ │ variable 1: ………………………………………………………… scalar                                                      │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘

┌──────────────────────────────────────────────────────────────────────────────────────────────────┐
│ DG{Float64}                                                                                      │
│ ═══════════                                                                                      │
│ basis: …………………………………………………………………………… LobattoLegendreBasis{Float64}(polydeg=3)                    │
│ mortar: ………………………………………………………………………… LobattoLegendreMortarL2{Float64}(polydeg=3)                 │
│ surface integral: ……………………………………………… SurfaceIntegralWeakForm                                     │
│ │ surface flux: …………………………………………………… FluxLaxFriedrichs(max_abs_speed)                            │
│ volume integral: ………………………………………………… VolumeIntegralWeakForm                                      │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘

┌──────────────────────────────────────────────────────────────────────────────────────────────────┐
│ AnalysisCallback                                                                                 │
│ ════════════════                                                                                 │
│ interval: …………………………………………………………………… 100                                                         │
│ analyzer: …………………………………………………………………… LobattoLegendreAnalyzer{Float64}(polydeg=6)                 │
│ │ error 1: ………………………………………………………………… l2_error                                                    │
│ │ error 2: ………………………………………………………………… linf_error                                                  │
│ │ integral 1: ………………………………………………………… entropy_timederivative                                      │
│ save analysis to file: ………………………………… no                                                          │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘

┌──────────────────────────────────────────────────────────────────────────────────────────────────┐
│ SaveSolutionCallback                                                                             │
│ ════════════════════                                                                             │
│ interval: …………………………………………………………………… 100                                                         │
│ solution variables: ………………………………………… cons2prim                                                   │
│ save initial solution: ………………………………… yes                                                         │
│ save final solution: ……………………………………… yes                                                         │
│ output directory: ……………………………………………… /home/runner/work/Ariadne.jl/…e.jl/docs/build/generated/out │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘

┌──────────────────────────────────────────────────────────────────────────────────────────────────┐
│ StepsizeCallback                                                                                 │
│ ════════════════                                                                                 │
│ CFL Hyperbolic: …………………………………………………… Returns{Float64}(1.6)                                       │
│ CFL Parabolic: ……………………………………………………… Returns{Float64}(0.0)                                       │
│ Interval: …………………………………………………………………… 1                                                           │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘

┌──────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Time integration                                                                                 │
│ ════════════════                                                                                 │
│ Start time: ……………………………………………………………… 0.0                                                         │
│ Final time: ……………………………………………………………… 1.0                                                         │
│ time integrator: ………………………………………………… TRBDF2                                                      │
│ adaptive: …………………………………………………………………… false                                                       │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Environment information                                                                          │
│ ═══════════════════════                                                                          │
│ #threads: …………………………………………………………………… 1                                                           │
│ threading backend: …………………………………………… static                                                      │
│ LoopVectorization: …………………………………………… disabled                                                    │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘

────────────────────────────────────────────────────────────────────────────────────────────────────
 Simulation running 'LinearScalarAdvectionEquation2D' with DGSEM(polydeg=3)
────────────────────────────────────────────────────────────────────────────────────────────────────
 #timesteps:                  0                run time:       1.40200000e-06 s
 Δt:             1.00000000e+00                └── GC time:    0.00000000e+00 s (0.000%)
 sim. time:      0.00000000e+00 (0.000%)       time/DOF/rhs!:  2.44941406e-08 s
                                               PID:                   Inf s
 #DOFs per field:          4096                alloc'd memory:        722.344 MiB
 #elements:                 256                device memory:           0.000 MiB

 Variable:       scalar
 L2 error:       3.94120825e-06
 Linf error:     1.23670425e-05
 ∑∂S/∂U ⋅ Uₜ :  -2.19124035e-16
────────────────────────────────────────────────────────────────────────────────────────────────────


────────────────────────────────────────────────────────────────────────────────────────────────────
 Simulation running 'LinearScalarAdvectionEquation2D' with DGSEM(polydeg=3)
────────────────────────────────────────────────────────────────────────────────────────────────────
 #timesteps:                 18                run time:       3.63493859e+01 s
 Δt:             5.55555556e-02                └── GC time:    2.64744400e-03 s (0.007%)
 sim. time:      1.00000000e+00 (100.000%)     time/DOF/rhs!:  2.35473231e-08 s
                                               PID:            6.01427476e-08 s
 #DOFs per field:          4096                alloc'd memory:        879.253 MiB
 #elements:                 256                device memory:           0.000 MiB

 Variable:       scalar
 L2 error:       1.71161806e-04
 Linf error:     2.52798213e-04
 ∑∂S/∂U ⋅ Uₜ :  -1.97752412e-09
────────────────────────────────────────────────────────────────────────────────────────────────────

────────────────────────────────────────────────────────────────────────────────────
             Trixi.jl                      Time                    Allocations
                                  ───────────────────────   ────────────────────────
        Tot / % measured:              36.4s /  39.1%            174MiB /   2.9%

Section                   ncalls     time    %tot     avg     alloc    %tot      avg
────────────────────────────────────────────────────────────────────────────────────
rhs!                        148k    14.2s  100.0%  96.4μs   4.78KiB    0.1%    0.03B
  volume integral           148k    9.77s   68.7%  66.2μs     0.00B    0.0%    0.00B
  interface flux            148k    1.16s    8.1%  7.85μs     0.00B    0.0%    0.00B
  Jacobian                  148k    1.04s    7.3%  7.02μs     0.00B    0.0%    0.00B
  surface integral          148k    1.03s    7.2%  6.96μs     0.00B    0.0%    0.00B
  prolong2interfaces        148k    982ms    6.9%  6.65μs     0.00B    0.0%    0.00B
  ~rhs!~                    148k    128ms    0.9%   869ns   4.78KiB    0.1%    0.03B
  reset ∂u/∂t               148k   91.6ms    0.6%   621ns     0.00B    0.0%    0.00B
  prolong2mortars           148k   6.58ms    0.0%  44.6ns     0.00B    0.0%    0.00B
  prolong2boundaries        148k   5.92ms    0.0%  40.1ns     0.00B    0.0%    0.00B
  mortar flux               148k   5.47ms    0.0%  37.1ns     0.00B    0.0%    0.00B
  boundary flux             148k   4.64ms    0.0%  31.5ns     0.00B    0.0%    0.00B
  source terms              148k   4.30ms    0.0%  29.2ns     0.00B    0.0%    0.00B
I/O                            3   1.94ms    0.0%   648μs    202KiB    3.9%  67.5KiB
  save solution                2   1.94ms    0.0%   969μs    199KiB    3.8%   100KiB
  ~I/O~                        3   3.95μs    0.0%  1.32μs   1.70KiB    0.0%     581B
  get element variables        2   1.49μs    0.0%   746ns   1.41KiB    0.0%     720B
  get node variables           2    842ns    0.0%   421ns     0.00B    0.0%    0.00B
  save mesh                    2    190ns    0.0%  95.0ns     0.00B    0.0%    0.00B
analyze solution               2   1.60ms    0.0%   802μs   4.87MiB   96.0%  2.44MiB
calculate dt                  19   65.0μs    0.0%  3.42μs   2.67KiB    0.1%     144B
────────────────────────────────────────────────────────────────────────────────────

Plot the solution

plot(Trixi.PlotData2DTriangulated(sol_sdrik.u[end], sol_sdrik.prob.p))

Increase CFL numbers

trixi_include(@__MODULE__, joinpath(examples_dir(), "tree_2d_dgsem", "elixir_advection_basic.jl"), cfl = 10, sol = nothing);

sol = solve(
    ode, Theseus.ImplicitEuler();
    dt = 1.0, # solve needs some value here but it will be overwritten by the stepsize_callback
    ode_default_options()..., callback = callbacks,
    # verbose=1,
    krylov_algo = :gmres,
    # krylov_kwargs=(;verbose=1)
);

@show callbacks.discrete_callbacks[4]
┌──────────────────────────────────────────────────────────────────────────────────────────────────┐
│ StepsizeCallback                                                                                 │
│ ════════════════                                                                                 │
│ CFL Hyperbolic: …………………………………………………… Returns{Int64}(10)                                          │
│ CFL Parabolic: ……………………………………………………… Returns{Float64}(0.0)                                       │
│ Interval: …………………………………………………………………… 1                                                           │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘

Plot the solution

plot(Trixi.PlotData2DTriangulated(sol.u[end], sol.prob.p))

This page was generated using Literate.jl.