Using the an implicit solver based on Ariadne with Trixi.jl
using Trixi
using Theseus
using CairoMakie
using LinearAlgebra
import Ariadne: JacobianOperatorNotes: 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_LOOPVECTORIZATIONLoad 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.000194 seconds (82 allocations: 8.719 KiB)
0.000130 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 │
│ maximum #cells: ……………………………………… 30000 │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 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/Ariadne.jl/docs/build/generated/out │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────────────────────────────────────────┐
│ StepsizeCallback │
│ ════════════════ │
│ CFL Advective: ………………………………………… Returns{Float64}(1.6) │
│ CFL Diffusive: ………………………………………… 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.15266475e+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.60069580e-08 s
PID: Inf s
#DOFs per field: 4096 alloc'd memory: 529.213 MiB
#elements: 256
Variable: scalar
L2 error: 3.94120825e-06
Linf error: 1.23670425e-05
∑∂S/∂U ⋅ Uₜ : -2.19124035e-16
────────────────────────────────────────────────────────────────────────────────────────────────────
┌ Warning: TODO forward zero-set of memorycopy used memset rather than runtime type
│ Caused by:
│ Stacktrace:
│ [1] copy
│ @ ./array.jl:350
│ [2] unaliascopy
│ @ ./abstractarray.jl:1516
│ [3] unalias
│ @ ./abstractarray.jl:1500
│ [4] broadcast_unalias
│ @ ./broadcast.jl:946
│ [5] preprocess
│ @ ./broadcast.jl:953
│ [6] preprocess_args
│ @ ./broadcast.jl:955
│ [7] preprocess
│ @ ./broadcast.jl:952
│ [8] override_bc_copyto!
│ @ ~/.julia/packages/Enzyme/xxXAx/src/compiler/interpreter.jl:818
│ [9] copyto!
│ @ ./broadcast.jl:925
│ [10] materialize!
│ @ ./broadcast.jl:883
│ [11] materialize!
│ @ ./broadcast.jl:880
│ [12] TRBDF2
│ @ ~/work/Ariadne.jl/Ariadne.jl/libs/Theseus/src/Theseus.jl:139
└ @ Enzyme.Compiler ~/.julia/packages/Enzyme/xxXAx/src/rules/llvmrules.jl:806
────────────────────────────────────────────────────────────────────────────────────────────────────
Simulation running 'LinearScalarAdvectionEquation2D' with DGSEM(polydeg=3)
────────────────────────────────────────────────────────────────────────────────────────────────────
#timesteps: 18 run time: 3.35525822e+01 s
Δt: 5.55555556e-02 └── GC time: 7.34405576e-01 s (2.189%)
sim. time: 1.00000000e+00 (100.000%) time/DOF/rhs!: 2.09705696e-08 s
PID: 1.47439366e-05 s
#DOFs per field: 4096 alloc'd memory: 459.842 MiB
#elements: 256
Variable: scalar
L2 error: 1.71224434e-04
Linf error: 2.52822142e-04
∑∂S/∂U ⋅ Uₜ : -1.97551223e-09
────────────────────────────────────────────────────────────────────────────────────────────────────
────────────────────────────────────────────────────────────────────────────────────
Trixi.jl Time Allocations
─────────────────────── ────────────────────────
Tot / % measured: 33.9s / 7.1% 1.21GiB / 4.0%
Section ncalls time %tot avg alloc %tot avg
────────────────────────────────────────────────────────────────────────────────────
I/O 3 2.13s 87.8% 709ms 29.0MiB 58.9% 9.66MiB
~I/O~ 3 1.64s 67.9% 548ms 17.3MiB 35.1% 5.76MiB
save solution 2 476ms 19.6% 238ms 11.1MiB 22.5% 5.54MiB
get element variables 2 6.40ms 0.3% 3.20ms 620KiB 1.2% 310KiB
get node variables 2 1.14μs 0.0% 571ns 0.00B 0.0% 0.00B
save mesh 2 441ns 0.0% 220ns 0.00B 0.0% 0.00B
analyze solution 2 250ms 10.3% 125ms 20.2MiB 41.1% 10.1MiB
rhs! 533 45.7ms 1.9% 85.7μs 4.78KiB 0.0% 9.19B
volume integral 533 30.5ms 1.3% 57.1μs 0.00B 0.0% 0.00B
interface flux 533 4.54ms 0.2% 8.51μs 0.00B 0.0% 0.00B
surface integral 533 3.37ms 0.1% 6.32μs 0.00B 0.0% 0.00B
prolong2interfaces 533 3.32ms 0.1% 6.22μs 0.00B 0.0% 0.00B
Jacobian 533 2.77ms 0.1% 5.19μs 0.00B 0.0% 0.00B
reset ∂u/∂t 533 560μs 0.0% 1.05μs 0.00B 0.0% 0.00B
~rhs!~ 533 533μs 0.0% 1.00μs 4.78KiB 0.0% 9.19B
prolong2mortars 533 40.3μs 0.0% 75.7ns 0.00B 0.0% 0.00B
prolong2boundaries 533 33.4μs 0.0% 62.6ns 0.00B 0.0% 0.00B
mortar flux 533 31.9μs 0.0% 59.8ns 0.00B 0.0% 0.00B
boundary flux 533 15.7μs 0.0% 29.5ns 0.00B 0.0% 0.00B
source terms 533 15.7μs 0.0% 29.4ns 0.00B 0.0% 0.00B
calculate dt 19 14.6μs 0.0% 771ns 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 │
│ maximum #cells: ……………………………………… 30000 │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 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/Ariadne.jl/docs/build/generated/out │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────────────────────────────────────────┐
│ StepsizeCallback │
│ ════════════════ │
│ CFL Advective: ………………………………………… Returns{Float64}(1.6) │
│ CFL Diffusive: ………………………………………… 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: 7.31000000e-07 s
Δt: 1.00000000e+00 └── GC time: 0.00000000e+00 s (0.000%)
sim. time: 0.00000000e+00 (0.000%) time/DOF/rhs!: 2.60349121e-08 s
PID: Inf s
#DOFs per field: 4096 alloc'd memory: 751.340 MiB
#elements: 256
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.90086146e+01 s
Δt: 5.55555556e-02 └── GC time: 8.47266883e-01 s (2.172%)
sim. time: 1.00000000e+00 (100.000%) time/DOF/rhs!: 2.36710427e-08 s
PID: 6.45502349e-08 s
#DOFs per field: 4096 alloc'd memory: 924.942 MiB
#elements: 256
Variable: scalar
L2 error: 1.71161806e-04
Linf error: 2.52798215e-04
∑∂S/∂U ⋅ Uₜ : -1.97752414e-09
────────────────────────────────────────────────────────────────────────────────────────────────────
────────────────────────────────────────────────────────────────────────────────────
Trixi.jl Time Allocations
─────────────────────── ────────────────────────
Tot / % measured: 39.0s / 36.7% 4.62GiB / 0.1%
Section ncalls time %tot avg alloc %tot avg
────────────────────────────────────────────────────────────────────────────────────
rhs! 148k 14.3s 99.9% 96.9μs 4.78KiB 0.1% 0.03B
volume integral 148k 9.77s 68.3% 66.2μs 0.00B 0.0% 0.00B
interface flux 148k 1.16s 8.1% 7.89μs 0.00B 0.0% 0.00B
surface integral 148k 1.10s 7.7% 7.49μs 0.00B 0.0% 0.00B
Jacobian 148k 1.00s 7.0% 6.79μs 0.00B 0.0% 0.00B
prolong2interfaces 148k 996ms 7.0% 6.75μs 0.00B 0.0% 0.00B
~rhs!~ 148k 126ms 0.9% 852ns 4.78KiB 0.1% 0.03B
reset ∂u/∂t 148k 100ms 0.7% 680ns 0.00B 0.0% 0.00B
prolong2boundaries 148k 6.30ms 0.0% 42.7ns 0.00B 0.0% 0.00B
mortar flux 148k 6.18ms 0.0% 41.9ns 0.00B 0.0% 0.00B
prolong2mortars 148k 5.77ms 0.0% 39.1ns 0.00B 0.0% 0.00B
boundary flux 148k 4.40ms 0.0% 29.8ns 0.00B 0.0% 0.00B
source terms 148k 4.32ms 0.0% 29.3ns 0.00B 0.0% 0.00B
analyze solution 2 9.23ms 0.1% 4.61ms 6.08MiB 96.7% 3.04MiB
I/O 3 1.77ms 0.0% 590μs 205KiB 3.2% 68.2KiB
save solution 2 1.76ms 0.0% 882μs 202KiB 3.1% 101KiB
~I/O~ 3 3.93μs 0.0% 1.31μs 1.70KiB 0.0% 581B
get element variables 2 1.28μs 0.0% 641ns 1.41KiB 0.0% 720B
get node variables 2 1.24μs 0.0% 621ns 0.00B 0.0% 0.00B
save mesh 2 159ns 0.0% 79.5ns 0.00B 0.0% 0.00B
calculate dt 19 68.5μs 0.0% 3.60μs 2.67KiB 0.0% 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 Advective: ………………………………………… Returns{Int64}(10) │
│ CFL Diffusive: ………………………………………… 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.