Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
trixi-framework
GitHub Repository: trixi-framework/Trixi.jl
Path: blob/main/examples/tree_2d_dgsem/elixir_advection_diffusion.jl
2055 views
1
using OrdinaryDiffEqLowStorageRK
2
using Trixi
3
4
###############################################################################
5
# semidiscretization of the linear advection-diffusion equation
6
7
advection_velocity = (1.5, 1.0)
8
equations = LinearScalarAdvectionEquation2D(advection_velocity)
9
diffusivity() = 5.0e-2
10
equations_parabolic = LaplaceDiffusion2D(diffusivity(), equations)
11
12
# Create DG solver with polynomial degree = 3 and (local) Lax-Friedrichs/Rusanov flux as surface flux
13
solver = DGSEM(polydeg = 3, surface_flux = flux_lax_friedrichs)
14
15
coordinates_min = (-1.0, -1.0) # minimum coordinates (min(x), min(y))
16
coordinates_max = (1.0, 1.0) # maximum coordinates (max(x), max(y))
17
18
# Create a uniformly refined mesh with periodic boundaries
19
mesh = TreeMesh(coordinates_min, coordinates_max,
20
initial_refinement_level = 4,
21
periodicity = true,
22
n_cells_max = 30_000) # set maximum capacity of tree data structure
23
24
# Define initial condition
25
function initial_condition_diffusive_convergence_test(x, t,
26
equation::LinearScalarAdvectionEquation2D)
27
# Store translated coordinate for easy use of exact solution
28
RealT = eltype(x)
29
x_trans = x - equation.advection_velocity * t
30
31
nu = diffusivity()
32
c = 1
33
A = 0.5f0
34
L = 2
35
f = 1.0f0 / L
36
omega = 2 * convert(RealT, pi) * f
37
scalar = c + A * sin(omega * sum(x_trans)) * exp(-2 * nu * omega^2 * t)
38
return SVector(scalar)
39
end
40
initial_condition = initial_condition_diffusive_convergence_test
41
42
# define periodic boundary conditions everywhere
43
boundary_conditions = boundary_condition_periodic
44
boundary_conditions_parabolic = boundary_condition_periodic
45
46
# A semidiscretization collects data structures and functions for the spatial discretization
47
semi = SemidiscretizationHyperbolicParabolic(mesh,
48
(equations, equations_parabolic),
49
initial_condition, solver;
50
solver_parabolic = ViscousFormulationBassiRebay1(),
51
boundary_conditions = (boundary_conditions,
52
boundary_conditions_parabolic))
53
54
###############################################################################
55
# ODE solvers, callbacks etc.
56
57
# Create ODE problem with time span from 0.0 to 1.5
58
tspan = (0.0, 1.5)
59
ode = semidiscretize(semi, tspan)
60
61
# At the beginning of the main loop, the SummaryCallback prints a summary of the simulation setup
62
# and resets the timers
63
summary_callback = SummaryCallback()
64
65
# The AnalysisCallback allows to analyse the solution in regular intervals and prints the results
66
analysis_interval = 100
67
analysis_callback = AnalysisCallback(semi, interval = analysis_interval)
68
69
# The AliveCallback prints short status information in regular intervals
70
alive_callback = AliveCallback(analysis_interval = analysis_interval)
71
72
# Create a CallbackSet to collect all callbacks such that they can be passed to the ODE solver
73
callbacks = CallbackSet(summary_callback, analysis_callback, alive_callback)
74
75
###############################################################################
76
# run the simulation
77
78
# OrdinaryDiffEq's `solve` method evolves the solution in time and executes the passed callbacks
79
alg = RDPK3SpFSAL49()
80
time_int_tol = 1.0e-11
81
sol = solve(ode, alg; abstol = time_int_tol, reltol = time_int_tol,
82
ode_default_options()..., callback = callbacks)
83
84