Burgers FDM Work-Precision Diagrams with Various MethodOfLines Methods

This benchmark is for the MethodOfLines package, which is an automatic PDE discretization package. It is concerned with comparing the performance of various discretization methods for the Burgers equation.

using MethodOfLines, DomainSets, OrdinaryDiffEq, ModelingToolkit, DiffEqDevTools, LinearAlgebra,
      LinearSolve, Plots

Here is the burgers equation with a Dirichlet and Neumann boundary conditions,

# pdesys1 has Dirichlet BCs, pdesys2 has Neumann BCs
const N = 30

@parameters x t
@variables u(..)
Dx = Differential(x)
Dt = Differential(t)
x_min = 0.0
x_max = 1.0
t_min = 0.0
t_max = 20.0

solver = FBDF()

analytic_u(p, t, x) = x / (t + 1)

analytic = [u(t, x) ~ analytic_u([], t, x)]

eq = Dt(u(t, x)) ~ -u(t, x) * Dx(u(t, x))

bcs1 = [u(0, x) ~ x,
    u(t, x_min) ~ analytic_u([], t, x_min),
    u(t, x_max) ~ analytic_u([], t, x_max)]

bcs2 = [u(0, x) ~ x,
    Dx(u(t, x_min)) ~ 1 / (t + 1),
    Dx(u(t, x_max)) ~ 1 / (t + 1)]

domains = [t ∈ Interval(t_min, t_max),
    x ∈ Interval(x_min, x_max)]

@named pdesys1 = PDESystem(eq, bcs1, domains, [t, x], [u(t, x)], analytic=analytic)
@named pdesys2 = PDESystem(eq, bcs2, domains, [t, x], [u(t, x)], analytic=analytic)
PDESystem
Equations: Symbolics.Equation[Differential(t)(u(t, x)) ~ -Differential(x)(u
(t, x))*u(t, x)]
Boundary Conditions: Symbolics.Equation[u(0, x) ~ x, Differential(x)(u(t, 0
.0)) ~ 1 / (1 + t), Differential(x)(u(t, 1.0)) ~ 1 / (1 + t)]
Domain: Symbolics.VarDomainPairing[Symbolics.VarDomainPairing(t, 0.0..20.0)
, Symbolics.VarDomainPairing(x, 0.0..1.0)]
Dependent Variables: Symbolics.Num[u(t, x)]
Independent Variables: Symbolics.Num[t, x]
Parameters: SciMLBase.NullParameters()
Default Parameter ValuesDict{Any, Any}()

Here is a uniform discretization with the Upwind scheme:

discupwind1 = MOLFiniteDifference([x => N], t, advection_scheme=UpwindScheme())
discupwind2 = MOLFiniteDifference([x => N-1], t, advection_scheme=UpwindScheme(), grid_align=edge_align)
MethodOfLines.MOLFiniteDifference{MethodOfLines.EdgeAlignedGrid, MethodOfLi
nes.ScalarizedDiscretization}(Dict{Symbolics.Num, Int64}(x => 29), t, 2, Me
thodOfLines.UpwindScheme(1), MethodOfLines.EdgeAlignedGrid(), true, false, 
MethodOfLines.ScalarizedDiscretization(), Base.Pairs{Symbol, Union{}, Tuple
{}, NamedTuple{(), Tuple{}}}())

Here is a uniform discretization with the WENO scheme:

discweno1 = MOLFiniteDifference([x => N], t, advection_scheme=WENOScheme())
discweno2 = MOLFiniteDifference([x => N-1], t, advection_scheme=WENOScheme(), grid_align=edge_align)
MethodOfLines.MOLFiniteDifference{MethodOfLines.EdgeAlignedGrid, MethodOfLi
nes.ScalarizedDiscretization}(Dict{Symbolics.Num, Int64}(x => 29), t, 2, Me
thodOfLines.WENOScheme(1.0e-6), MethodOfLines.EdgeAlignedGrid(), true, fals
e, MethodOfLines.ScalarizedDiscretization(), Base.Pairs{Symbol, Union{}, Tu
ple{}, NamedTuple{(), Tuple{}}}())

Here is a non-uniform discretization with the Upwind scheme, using tanh (nonuniform WENO is not implemented yet):


gridnu1 = chebyspace(domains[2], N)
gridnu2 = chebyspace(domains[2], N-1)

discnu1 = MOLFiniteDifference([x => gridnu1], t, advection_scheme=UpwindScheme())
discnu2 = MOLFiniteDifference([x => gridnu2], t, advection_scheme=UpwindScheme(), grid_align=edge_align)
Error: type Int64 has no field domain

Here are the problems for pdesys1:

probupwind1 = discretize(pdesys1, discupwind1; analytic=pdesys1.analytic_func)
probupwind2 = discretize(pdesys1, discupwind2; analytic=pdesys1.analytic_func)

probweno1 = discretize(pdesys1, discweno1; analytic=pdesys1.analytic_func)
probweno2 = discretize(pdesys1, discweno2; analytic=pdesys1.analytic_func)

probnu1 = discretize(pdesys1, discnu1; analytic=pdesys1.analytic_func)
probnu2 = discretize(pdesys1, discnu2; analytic=pdesys1.analytic_func)

probs1 = [probupwind1, probupwind2, probnu1, probnu2, probweno1, probweno2]
Error: UndefVarError: discnu1 not defined

Some of the types have been truncated in the stacktrace for improved readin
g. To emit complete information
in the stack trace, evaluate `TruncatedStacktraces.VERBOSE[] = true` and re
-run the code.

Work-Precision Plot for Burgers Equation, Dirichlet BCs

dummy_appxsol = [nothing for i in 1:length(probs1)]
abstols = 1.0 ./ 10.0 .^ (5:8)
reltols = 1.0 ./ 10.0 .^ (1:4);
setups = [Dict(:alg => solver, :prob_choice => 1),
    Dict(:alg => solver, :prob_choice => 2),
    Dict(:alg => solver, :prob_choice => 3),
    Dict(:alg => solver, :prob_choice => 4),
    Dict(:alg => solver, :prob_choice => 5),
    Dict(:alg => solver, :prob_choice => 6),]
names = ["Uniform Upwind, center_align", "Uniform Upwind, edge_align", "Nonuniform Upwind, center_align",
         "Nonuniform Upwind, edge_align", "WENO, center_align", "WENO, edge_align"];

wp = WorkPrecisionSet(probs1, abstols, reltols, setups; names=names,
    save_everystep=false, appxsol = dummy_appxsol, maxiters=Int(1e5),
    numruns=10, wrap=Val(false))
plot(wp)
Error: UndefVarError: probs1 not defined

Some of the types have been truncated in the stacktrace for improved readin
g. To emit complete information
in the stack trace, evaluate `TruncatedStacktraces.VERBOSE[] = true` and re
-run the code.

Here are the problems for pdesys2:

probupwind1 = discretize(pdesys2, discupwind1; analytic=pdesys2.analytic_func)
probupwind2 = discretize(pdesys2, discupwind2; analytic=pdesys2.analytic_func)

probweno1 = discretize(pdesys2, discweno1; analytic=pdesys2.analytic_func)
probweno2 = discretize(pdesys2, discweno2; analytic=pdesys2.analytic_func)

probnu1 = discretize(pdesys2, discnu1; analytic=pdesys2.analytic_func)
probnu2 = discretize(pdesys2, discnu2; analytic=pdesys2.analytic_func)

probs2 = [probupwind1, probupwind2, probnu1, probnu2, probweno1, probweno2]
Error: UndefVarError: discnu1 not defined

Some of the types have been truncated in the stacktrace for improved readin
g. To emit complete information
in the stack trace, evaluate `TruncatedStacktraces.VERBOSE[] = true` and re
-run the code.

Work-Precision Plot for Burgers Equation, Neumann BCs

abstols = 1.0 ./ 10.0 .^ (5:8)
reltols = 1.0 ./ 10.0 .^ (1:4);
setups = [Dict(:alg => solver, :prob_choice => 1),
          Dict(:alg => solver, :prob_choice => 2),
          Dict(:alg => solver, :prob_choice => 3),
          Dict(:alg => solver, :prob_choice => 4),
          Dict(:alg => solver, :prob_choice => 5),
          Dict(:alg => solver, :prob_choice => 6),]
names = ["Uniform Upwind, center_align", "Uniform Upwind, edge_align", "Nonuniform Upwind, center_align",
         "Nonuniform Upwind, edge_align", "WENO, center_align", "WENO, edge_align"];

wp = WorkPrecisionSet(probs2, abstols, reltols, setups; names=names,
                      save_everystep=false, maxiters=Int(1e5),
                      numruns=10, wrap=Val(false))
plot(wp)
Error: UndefVarError: probs2 not defined

Some of the types have been truncated in the stacktrace for improved readin
g. To emit complete information
in the stack trace, evaluate `TruncatedStacktraces.VERBOSE[] = true` and re
-run the code.