Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
trixi-framework
GitHub Repository: trixi-framework/Trixi.jl
Path: blob/main/examples/dgmulti_2d/elixir_advection_diffusion_nonperiodic.jl
2055 views
1
using OrdinaryDiffEqLowStorageRK
2
using Trixi
3
4
dg = DGMulti(polydeg = 3, element_type = Quad(), approximation_type = Polynomial(),
5
surface_integral = SurfaceIntegralWeakForm(flux_lax_friedrichs),
6
volume_integral = VolumeIntegralWeakForm())
7
8
diffusivity() = 5.0e-2
9
10
equations = LinearScalarAdvectionEquation2D(1.0, 0.0)
11
equations_parabolic = LaplaceDiffusion2D(diffusivity(), equations)
12
13
# Example setup taken from
14
# - Truman Ellis, Jesse Chan, and Leszek Demkowicz (2016).
15
# Robust DPG methods for transient convection-diffusion.
16
# In: Building bridges: connections and challenges in modern approaches
17
# to numerical partial differential equations.
18
# [DOI](https://doi.org/10.1007/978-3-319-41640-3_6).
19
function initial_condition_erikkson_johnson(x, t, equations)
20
l = 4
21
epsilon = diffusivity() # Note: this requires epsilon < 0.6 due to the sqrt
22
lambda_1 = (-1 + sqrt(1 - 4 * epsilon * l)) / (-2 * epsilon)
23
lambda_2 = (-1 - sqrt(1 - 4 * epsilon * l)) / (-2 * epsilon)
24
r1 = (1 + sqrt(1 + 4 * pi^2 * epsilon^2)) / (2 * epsilon)
25
s1 = (1 - sqrt(1 + 4 * pi^2 * epsilon^2)) / (2 * epsilon)
26
u = exp(-l * t) * (exp(lambda_1 * x[1]) - exp(lambda_2 * x[1])) +
27
cos(pi * x[2]) * (exp(s1 * x[1]) - exp(r1 * x[1])) / (exp(-s1) - exp(-r1))
28
return SVector{1}(u)
29
end
30
initial_condition = initial_condition_erikkson_johnson
31
32
# tag different boundary segments
33
left(x, tol = 50 * eps()) = abs(x[1] + 1) < tol
34
right(x, tol = 50 * eps()) = abs(x[1]) < tol
35
bottom(x, tol = 50 * eps()) = abs(x[2] + 0.5) < tol
36
top(x, tol = 50 * eps()) = abs(x[2] - 0.5) < tol
37
entire_boundary(x, tol = 50 * eps()) = true
38
is_on_boundary = Dict(:left => left, :right => right, :top => top, :bottom => bottom,
39
:entire_boundary => entire_boundary)
40
41
cells_per_dimension = (16, 16)
42
mesh = DGMultiMesh(dg, cells_per_dimension;
43
coordinates_min = (-1.0, -0.5),
44
coordinates_max = (0.0, 0.5),
45
is_on_boundary)
46
47
# BC types
48
boundary_condition = BoundaryConditionDirichlet(initial_condition)
49
50
# define inviscid boundary conditions, enforce "do nothing" boundary condition at the outflow
51
boundary_conditions = (; :left => boundary_condition,
52
:top => boundary_condition,
53
:bottom => boundary_condition,
54
:right => boundary_condition_do_nothing)
55
56
# define viscous boundary conditions
57
boundary_conditions_parabolic = (; :entire_boundary => boundary_condition)
58
59
semi = SemidiscretizationHyperbolicParabolic(mesh, (equations, equations_parabolic),
60
initial_condition, dg;
61
boundary_conditions = (boundary_conditions,
62
boundary_conditions_parabolic))
63
64
tspan = (0.0, 1.5)
65
ode = semidiscretize(semi, tspan)
66
67
summary_callback = SummaryCallback()
68
alive_callback = AliveCallback(alive_interval = 10)
69
analysis_interval = 100
70
analysis_callback = AnalysisCallback(semi, interval = analysis_interval, uEltype = real(dg))
71
save_solution = SaveSolutionCallback(interval = analysis_interval,
72
solution_variables = cons2prim)
73
callbacks = CallbackSet(summary_callback, alive_callback, analysis_callback, save_solution)
74
75
###############################################################################
76
# run the simulation
77
78
time_int_tol = 1e-8
79
sol = solve(ode, RDPK3SpFSAL49(); abstol = time_int_tol, reltol = time_int_tol,
80
ode_default_options()..., callback = callbacks)
81
82